Compare commits

..

33 Commits

Author SHA1 Message Date
AFCMS 1504d64647
Merge branch 'master' into dyable-leather-armor 2022-05-02 09:56:11 +02:00
AFCMS 132529d8f4
theorically support enchantments 2022-05-01 01:53:51 +02:00
AFCMS a3d2761215
better colored leather textures + optipng -o7 -zm1-9 -nc -strip all -clobber 2022-05-01 01:49:23 +02:00
AFCMS 0e42e58901
Get rid of the 2d preview 2022-05-01 01:36:47 +02:00
AFCMS f6f0690253
remove 2d inventory preview 2022-05-01 01:13:30 +02:00
AFCMS a7484b1389
working coloring 2022-05-01 01:09:21 +02:00
AFCMS 56d14619cd
stuff 2022-05-01 00:58:43 +02:00
AFCMS 459f142fc5
add basic tooltip to colored armor 2022-05-01 00:52:25 +02:00
AFCMS d9fef2966f
oops 2022-05-01 00:37:27 +02:00
AFCMS 126d74b428
fix mcl_armor inventory images 2022-05-01 00:37:22 +02:00
AFCMS b4611dc20f
some fixes 2022-05-01 00:27:37 +02:00
AFCMS 95e165b50b
Merge branch 'master' into dyable-leather-armor 2022-05-01 00:16:23 +02:00
AFCMS 45ca8dfbfb Merge branch 'master' into dyable-leather-armor 2021-05-27 09:09:52 +02:00
AFCMS 39481d8b10 Merge branch 'master' into dyable-leather-armor 2021-05-19 00:19:58 +02:00
AFCMS 422d48f658 Merge branch 'master' into dyable-leather-armor 2021-05-10 09:39:20 +02:00
AFCMS c1eefab8d6 Merge branch 'master' into dyable-leather-armor 2021-05-04 10:30:10 +02:00
AFCMS e573dd25e1 Merge branch 'master' into dyable-leather-armor 2021-05-03 23:26:05 +02:00
AFCMS 98226d677c not working implementation of colored leather armors 2021-04-29 16:47:18 +02:00
AFCMS 547291c333 restart form scratch 2021-04-29 16:24:34 +02:00
AFCMS 5637b649e8 fix merge 2021-04-29 16:23:24 +02:00
AFCMS 16b4a6e5c2 Merge branch 'master' into dyable-leather-armor 2021-04-29 16:22:32 +02:00
AFCMS fb0a687bdc Merge branch 'master' into dyable-leather-armor 2021-04-16 13:45:05 +02:00
AFCMS 2aa7218126 Merge branch 'master' into dyable-leather-armor 2021-04-13 12:12:00 +02:00
AFCMS e0aa16cf06 Merge branch 'master' into dyable-leather-armor 2021-03-31 20:33:28 +02:00
AFCMS 69629d4ca3 Merge branch 'master' into dyable-leather-armor 2021-03-31 16:15:44 +02:00
AFCMS e7166430d7 Merge branch 'master' into dyable-leather-armor 2021-03-30 22:28:25 +02:00
AFCMS 31027aca2e Avoid unnecessary registration 2021-03-29 21:39:04 +02:00
AFCMS 9990db92b4 Revert "Revert "Update leather.lua""
This reverts commit c1ea059a14.
2021-03-29 21:35:15 +02:00
AFCMS c1ea059a14 Revert "Update leather.lua"
This reverts commit a01813e421.
2021-03-29 21:33:46 +02:00
AFCMS a01813e421 Update leather.lua 2021-03-29 21:33:27 +02:00
AFCMS d7ae8c62db Merge branch 'master' into dyable-leather-armor 2021-03-29 18:50:52 +02:00
AFCMS 2d585c9517 basic dyable armors 2021-03-29 18:39:23 +02:00
AFCMS 896b213f17 optimisation 2021-03-27 08:02:50 +01:00
859 changed files with 8625 additions and 21974 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` * Buckets: `ITEMS/mcl_buckets`
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers` * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
### Mobs ## Mobs
* Mobs: `ENTITIES/mcl_mobs` * Mobs: `ENTITIES/mcl_mobs`
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short. MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.

View File

@ -27,11 +27,6 @@
* Code-Sploit * Code-Sploit
* NO11 * NO11
* kabou * kabou
* rudzik8
* chmodsayshello
* PrarieWind
* RandomLegoBrick
* SumianVoice
## Contributors ## Contributors
* Laurent Rocher * Laurent Rocher
@ -76,12 +71,6 @@
* Sven792 * Sven792
* aldum * aldum
* Dieter44 * Dieter44
* Pepebotella
* MrRar
* Lazerbeak12345
* mrminer
* Thunder1035
* opfromthestart
## MineClone5 ## MineClone5
* kay27 * kay27
@ -89,12 +78,10 @@
* epCode * epCode
* NO11 * NO11
* j45 * j45
* chmodsayshello
* 3raven * 3raven
* PrarieWind * PrarieWind
* Gustavo1 * Gustavo1
* CableGuy67 * CableGuy67
* MrRar
## Mineclonia ## Mineclonia
* erlehmann * erlehmann
@ -147,9 +134,6 @@
* yutyo * yutyo
* NO11 * NO11
* kay27 * kay27
* MysticTempest
* RandomLegoBrick
* cora
## Translations ## Translations
* Wuzzy * Wuzzy
@ -159,8 +143,6 @@
* pitchum * pitchum
* todoporlalibertad * todoporlalibertad
* Marcin Serwin * Marcin Serwin
* Pepebotella
* Emojigit
## Funders ## Funders
* 40W * 40W
@ -168,6 +150,5 @@
## Special thanks ## Special thanks
* celeron55 for creating Minetest * celeron55 for creating Minetest
* Jordach for the jukebox music compilation from Big Freaking Dig * 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 * 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 * Notch and Jeb for being the major forces behind Minecraft

View File

@ -102,8 +102,6 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
* `water_bucket=1`: Bucket containing a liquid of group “water” * `water_bucket=1`: Bucket containing a liquid of group “water”
* `enchantability=X`: How good the enchantments are the item gets (1 equals book) * `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 * `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 ### Material groups
@ -205,9 +203,6 @@ These groups are used mostly for informational purposes
* `building_block=1`: Block is a building block * `building_block=1`: Block is a building block
* `deco_block=1`: Block is a decorational 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 ## Fake item groups
These groups put similar items together which should all be treated by the gameplay or the GUI as a single item. 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. An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB. Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.79 (in development) Version: 0.75 (in development)
### Gameplay ### Gameplay
You start in a randomly-generated world made entirely of cubes. You can explore 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 ## Target
- Crucially, create a stable, moddable, free/libre clone of Minecraft - Crucially, create a stable, moddable, free/libre clone of Minecraft
based on the Minetest engine with polished features, usable in both based on the Minetest engine with polished features, usable in both
singleplayer and multiplayer. Currently, a lot of **Minecraft Java singleplayer and multiplayer. Currently, most of **Minecraft Java
Edition** features are already implemented and polishing existing Edition 1.12.2** features are already implemented and polishing existing
features are prioritized over new feature requests. features are prioritized over new feature requests.
- With lessened priority yet strictly, implement features targetting - 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 by the Minetest Engine). This means features in parity with the listed
Minecraft experiences are prioritized over those that don't fulfill this Minecraft experiences are prioritized over those that don't fulfill this
scope. scope.
@ -108,7 +108,8 @@ playerbase on low spec computers, optimizations are hard to investigate.
This game is currently in **beta** stage. This game is currently in **beta** stage.
It is playable, but not yet feature-complete. It is playable, but not yet feature-complete.
Backwards-compability is not entirely guaranteed, updating your world might cause small bugs. 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: The following main features are available:
@ -123,7 +124,7 @@ The following main features are available:
* Most blocks in the overworld * Most blocks in the overworld
* Water and lava * Water and lava
* Weather * Weather
* 28 biomes + 5 Nether Biomes * 28 biomes
* The Nether, a fiery underworld in another dimension * The Nether, a fiery underworld in another dimension
* Redstone circuits (partially) * Redstone circuits (partially)
* Minecarts (partial) * Minecarts (partial)
@ -161,7 +162,7 @@ The following features are incomplete:
* Special minecarts * Special minecarts
* A couple of non-trivial blocks and items * 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 * 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 * 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 * Nether Brick Fence Gate
* Red Nether Brick Fence * Red Nether Brick Fence
* Red Nether Brick Fence Gate * 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: 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. description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.

View File

@ -14,7 +14,7 @@ mcl_damage = {
cactus = {}, cactus = {},
fall = {bypasses_armor = true}, fall = {bypasses_armor = true},
fly_into_wall = {bypasses_armor = true}, -- unused 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}, generic = {bypasses_armor = true},
magic = {is_magic = true, 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 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
@ -78,7 +78,7 @@ function mcl_damage.from_punch(mcl_reason, object)
mcl_reason.type = "arrow" mcl_reason.type = "arrow"
elseif luaentity._is_fireball then elseif luaentity._is_fireball then
mcl_reason.type = "fireball" mcl_reason.type = "fireball"
elseif luaentity.is_mob then elseif luaentity._cmi_is_mob then
mcl_reason.type = "mob" mcl_reason.type = "mob"
end end
mcl_reason.source = mcl_reason.source or luaentity._source_object mcl_reason.source = mcl_reason.source or luaentity._source_object
@ -161,9 +161,9 @@ minetest.register_on_dieplayer(function(player, mt_reason)
if mt_reason.approved then if mt_reason.approved then
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason)) mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
end end
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
end) end)
minetest.register_on_mods_loaded(function() minetest.register_on_mods_loaded(function()
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
end) end)

View File

@ -337,6 +337,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
if not obj:is_player() then if not obj:is_player() then
return return
end 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)) obj:add_velocity(vector.multiply(punch_dir, impact * 20))

View File

@ -524,7 +524,7 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
if luaentity.deal_damage then if luaentity.deal_damage then
luaentity:deal_damage(damage, mcl_reason or {type = "generic"}) luaentity:deal_damage(damage, mcl_reason or {type = "generic"})
return return
elseif luaentity.is_mob then elseif luaentity._cmi_is_mob then
-- local puncher = mcl_reason and mcl_reason.direct or target -- 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) -- 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 if luaentity.health > 0 then
@ -544,7 +544,7 @@ end
function mcl_util.get_hp(obj) function mcl_util.get_hp(obj)
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
if luaentity and luaentity.is_mob then if luaentity and luaentity._cmi_is_mob then
return luaentity.health return luaentity.health
else else
return obj:get_hp() return obj:get_hp()

View File

@ -28,10 +28,11 @@ end)
local timer = 0 local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime timer = timer + dtime
if timer >= 0.6 then if timer >= 0.3 then
for _, player in pairs(get_connected_players()) do for _, player in pairs(get_connected_players()) do
local ppos = player:get_pos() 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 if npos then
local node = get_node(npos) local node = get_node(npos)
if node then if node then

View File

@ -13,21 +13,11 @@ local function is_group(pos, group)
end end
local is_water = flowlib.is_water 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) local function is_ice(pos)
return is_group(pos, "ice") return is_group(pos, "ice")
end end
local function is_fire(pos)
return is_group(pos, "set_on_fire")
end
local function get_sign(i) local function get_sign(i)
if i == 0 then if i == 0 then
return 0 return 0
@ -120,11 +110,9 @@ end
local boat = { local boat = {
physical = true, physical = true,
pointable = true,
-- Warning: Do not change the position of the collisionbox top surface, -- Warning: Do not change the position of the collisionbox top surface,
-- lowering it causes the boat to fall through the world if underwater -- lowering it causes the boat to fall through the world if underwater
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7},
visual = "mesh", visual = "mesh",
mesh = "mcl_boats_boat.b3d", mesh = "mcl_boats_boat.b3d",
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"}, 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"},
@ -206,8 +194,6 @@ end
function boat.on_step(self, dtime, moveresult) function boat.on_step(self, dtime, moveresult)
mcl_burning.tick(self.object, dtime, self) 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) self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
local v_factor = 1 local v_factor = 1
@ -216,21 +202,16 @@ function boat.on_step(self, dtime, moveresult)
local on_water = true local on_water = true
local on_ice = false local on_ice = false
local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) 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} local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z}
if not is_water(waterp) then if not is_water(waterp) then
on_water = false on_water = false
if not in_water and is_ice(waterp) then if not in_water and is_ice(waterp) then
on_ice = true 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 else
v_slowdown = 0.04 v_slowdown = 0.04
v_factor = 0.5 v_factor = 0.5
end end
elseif in_water and not in_river_water then elseif in_water then
on_water = false on_water = false
in_water = true in_water = true
v_factor = 0.75 v_factor = 0.75
@ -333,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 for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
local entity = obj:get_luaentity() local entity = obj:get_luaentity()
if entity and entity.is_mob then if entity and entity._cmi_is_mob then
attach_object(self, obj) attach_object(self, obj)
break break
end end
@ -362,18 +343,7 @@ function boat.on_step(self, dtime, moveresult)
else else
p.y = p.y + 1 p.y = p.y + 1
local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian" local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian"
if is_river_water(p) then if is_water(p) or is_obsidian_boat 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
-- Inside water: Slowly sink -- Inside water: Slowly sink
local y = self.object:get_velocity().y local y = self.object:get_velocity().y
y = y - 0.01 y = y - 0.01

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. 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 Spruce Boat=Bateau en Sapin
Water vehicle=Véhicule aquatique Water vehicle=Véhicule aquatique
Sneak to dismount=Se baisser pour descendre Sneak to dismount=
Obsidian Boat=Bateau en Obsidienne

View File

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

View File

@ -134,7 +134,6 @@ function mcl_burning.set_on_fire(obj, burn_time)
end end
function mcl_burning.extinguish(obj) function mcl_burning.extinguish(obj)
if not obj:get_pos() then return end
if mcl_burning.is_burning(obj) then if mcl_burning.is_burning(obj) then
local storage = mcl_burning.get_storage(obj) local storage = mcl_burning.get_storage(obj)
if obj:is_player() then if obj:is_player() then

View File

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

View File

@ -1,55 +1,66 @@
-- Dripping Water Mod -- Dripping Water Mod
-- by kddekadenz -- by kddekadenz
-- License of code, textures & sounds: CC0
local math = math local math = math
local function make_drop(pos,liquid,sound,interval)
local pt = {
velocity = vector.new(0,0,0),
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.new(0,0,0)
pt.collisiondetection = false
pt.expirationtime = t
pt.texture="[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png" -- License of code, textures & sounds: CC0
minetest.add_particle(pt)
minetest.after(t,function() local function register_drop(liquid, glow, sound, nodes)
pt.acceleration = vector.new(0,-5,0) minetest.register_entity("mcl_dripping:drop_" .. liquid, {
pt.collisiondetection = true hp_max = 1,
pt.expirationtime = math.random() + math.random(1, interval/2) physical = true,
minetest.add_particle(pt) collide_with_objects = false,
minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = pos, gain = 0.5, max_hear_distance = 8}, true) collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01},
end) glow = glow,
end) 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 end
if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then
local function register_drop(liquid, glow, sound, nodes, interval, chance) 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({ minetest.register_abm({
label = "Create drops", label = "Create drops",
nodenames = nodes, nodenames = nodes,
neighbors = {"group:" .. liquid}, neighbors = {"group:" .. liquid},
interval = interval, interval = 2,
chance = chance, chance = 22,
action = function(pos) action = function(pos)
local r = math.ceil(interval / 20) if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0
local nn=minetest.find_nodes_in_area(vector.offset(pos,-r,0,-r),vector.offset(pos,r,0,r),nodes) and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then
--start a bunch of particle cycles to be able to get away local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
--with longer abm cycles minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid)
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, liquid) ~= 0
and minetest.get_node(vector.offset(nn[i], 0, -1, 0)).name == "air" then
make_drop(nn[i],liquid,sound,interval)
end
end end
end, end,
}) })
end end
register_drop("water", 1, "", {"group:opaque", "group:leaves"},60,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"},60,10) register_drop("lava", math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), "lava", {"group:opaque"})

View File

@ -59,8 +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:blaze_rod", "mcl:blazeRod")
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") 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: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")
local function check_pickup_achievements(object, player) local function check_pickup_achievements(object, player)
if has_awards then if has_awards then
@ -80,6 +78,7 @@ local function enable_physics(object, luaentity, ignore_check)
object:set_properties({ object:set_properties({
physical = true physical = true
}) })
object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=-get_gravity(),z=0}) object:set_acceleration({x=0,y=-get_gravity(),z=0})
end end
end end
@ -318,14 +317,18 @@ function minetest.handle_node_drops(pos, drops, digger)
-- Spawn item and apply random speed -- Spawn item and apply random speed
local obj = minetest.add_item(dpos, drop_item) local obj = minetest.add_item(dpos, drop_item)
if obj then if obj then
-- set the velocity multiplier to the stored amount or if the game dug this node, apply a bigger velocity local x = math.random(1, 5)
local v = 1 if math.random(1,2) == 1 then
if digger and digger:is_player() then x = -x
obj:get_luaentity().random_velocity = 1
else
obj:get_luaentity().random_velocity = 1.6
end 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().age = item_drop_settings.dug_buffer
obj:get_luaentity()._insta_collect = false obj:get_luaentity()._insta_collect = false
end end
end end
@ -404,33 +407,9 @@ minetest.register_entity(":__builtin:item", {
-- Number of seconds this item entity has existed so far -- Number of seconds this item entity has existed so far
age = 0, age = 0,
-- Multiplier for initial random velocity when the item is spawned
random_velocity = 1,
-- How old it has become in the collection animation -- How old it has become in the collection animation
collection_age = 0, 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) set_item = function(self, itemstring)
self.itemstring = itemstring self.itemstring = itemstring
if self.itemstring == "" then if self.itemstring == "" then
@ -439,11 +418,7 @@ minetest.register_entity(":__builtin:item", {
end end
local stack = ItemStack(itemstring) local stack = ItemStack(itemstring)
if minetest.get_item_group(stack:get_name(), "compass") > 0 then if minetest.get_item_group(stack:get_name(), "compass") > 0 then
if string.find(stack:get_name(), "_lodestone") then stack:set_name("mcl_compass:16")
stack:set_name("mcl_compass:18_lodestone")
else
stack:set_name("mcl_compass:18")
end
itemstring = stack:to_string() itemstring = stack:to_string()
self.itemstring = itemstring self.itemstring = itemstring
end end
@ -483,9 +458,27 @@ minetest.register_entity(":__builtin:item", {
glow = glow, glow = glow,
} }
self.object:set_properties(prop) self.object:set_properties(prop)
if item_drop_settings.random_item_velocity == true and self.age < 1 then if item_drop_settings.random_item_velocity == true then
minetest.after(0, self.apply_random_vel, self) minetest.after(0, function(self)
if not self or not self.object or not self.object:get_luaentity() then
return
end 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, end,
get_staticdata = function(self) get_staticdata = function(self)
@ -539,9 +532,9 @@ minetest.register_entity(":__builtin:item", {
self.itemstring = data.itemstring self.itemstring = data.itemstring
self.always_collect = data.always_collect self.always_collect = data.always_collect
if data.age then if data.age then
self.age = data.age self.age = data.age + dtime_s
else else
self.age = self.age self.age = dtime_s
end end
--remember collection data --remember collection data
-- If true, can collect item without delay -- If true, can collect item without delay
@ -574,7 +567,7 @@ minetest.register_entity(":__builtin:item", {
self._forcetimer = 0 self._forcetimer = 0
self.object:set_armor_groups({immortal = 1}) 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.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
self:set_item(self.itemstring) self:set_item(self.itemstring)
end, end,
@ -604,13 +597,12 @@ minetest.register_entity(":__builtin:item", {
end end
-- Merge the remote stack into this one -- Merge the remote stack into this one
-- local pos = object:get_pos() local pos = object:get_pos()
-- pos.y = pos.y + ((total_count - count) / max_count) * 0.15 pos.y = pos.y + ((total_count - count) / max_count) * 0.15
-- self.object:move_to(pos) self.object:move_to(pos)
self.age = 0 -- Handle as new entity self.age = 0 -- Handle as new entity
own_stack:set_count(total_count) own_stack:set_count(total_count)
self.random_velocity = 0
self:set_item(own_stack:to_string()) self:set_item(own_stack:to_string())
entity._removed = true entity._removed = true
@ -649,53 +641,33 @@ minetest.register_entity(":__builtin:item", {
local node = minetest.get_node_or_nil(p) local node = minetest.get_node_or_nil(p)
local in_unloaded = (node == nil) 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 if self.is_clock then
self.object:set_properties({ self.object:set_properties({
textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)} textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)}
}) })
end 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 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 if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then
self._magnet_active = false self._magnet_active = false
enable_physics(self.object, self) enable_physics(self.object, self)
return return
end 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 -- Destroy item in lava, fire or special nodes
local nn = node.name
local def = minetest.registered_nodes[nn] local def = minetest.registered_nodes[nn]
local lg = minetest.get_item_group(nn, "lava") local lg = minetest.get_item_group(nn, "lava")
local fg = minetest.get_item_group(nn, "fire") local fg = minetest.get_item_group(nn, "fire")
local dg = minetest.get_item_group(nn, "destroys_items") local dg = minetest.get_item_group(nn, "destroys_items")
if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then 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. --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 if dg ~= 2 then
minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5}) minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5})
end end
@ -718,7 +690,7 @@ minetest.register_entity(":__builtin:item", {
end end
-- Push item out when stuck inside solid opaque node -- 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 shootdir
local cx = (p.x % 1) - 0.5 local cx = (p.x % 1) - 0.5
local cz = (p.z % 1) - 0.5 local cz = (p.z % 1) - 0.5
@ -759,8 +731,8 @@ minetest.register_entity(":__builtin:item", {
local newv = vector.multiply(shootdir, 3) local newv = vector.multiply(shootdir, 3)
self.object:set_acceleration({x = 0, y = 0, z = 0}) self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity(newv) self.object:set_velocity(newv)
disable_physics(self.object, self, false, false)
disable_physics(self.object, self, false, false)
if shootdir.y == 0 then if shootdir.y == 0 then
self._force = newv self._force = newv
@ -798,9 +770,8 @@ minetest.register_entity(":__builtin:item", {
return return
end 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. -- Move item around on flowing liquids
if def and not is_floating and (def.liquidtype == "flowing" or def.liquidtype == "source") then if def and def.liquidtype == "flowing" then
self._flowing = true
--[[ Get flowing direction (function call from flowlib), if there's a liquid. --[[ 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. NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
@ -809,11 +780,11 @@ minetest.register_entity(":__builtin:item", {
-- Just to make sure we don't manipulate the speed for no reason -- 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 if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" -- 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 -- Set new item moving speed into the direciton of the liquid
local newv = vector.multiply(vec, f) local newv = vector.multiply(vec, f)
-- Swap to acceleration instead of a static speed to better mimic MC mechanics. self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = newv.x, y = -0.22, z = newv.z}) self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
self.physical_state = true self.physical_state = true
self._flowing = true self._flowing = true
@ -822,29 +793,7 @@ minetest.register_entity(":__builtin:item", {
}) })
return return
end end
if is_in_water and def.liquidtype == "source" then elseif self._flowing == true 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
-- Disable flowing physics if not on/in flowing liquid -- Disable flowing physics if not on/in flowing liquid
self._flowing = false self._flowing = false
enable_physics(self.object, self, true) enable_physics(self.object, self, true)
@ -853,13 +802,10 @@ minetest.register_entity(":__builtin:item", {
-- If node is not registered or node is walkably solid and resting on nodebox -- 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 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 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] if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then
or is_floating or is_on_floor then if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring) local own_stack = ItemStack(self.object:get_luaentity().itemstring)
-- Merge with close entities of the same item -- Merge with close entities of the same item
for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
@ -870,17 +816,14 @@ minetest.register_entity(":__builtin:item", {
return return
end end
end end
-- don't disable if underwater end
if not is_in_water then
disable_physics(self.object, self) disable_physics(self.object, self)
end end
end
else else
if self._magnet_active == false and not is_floating then if self._magnet_active == false then
enable_physics(self.object, self) enable_physics(self.object, self)
end end
end end
end, end,
-- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching -- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching

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é 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 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é 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

@ -21,7 +21,7 @@ local function register_rail(itemstring, tiles, def_extras, creative)
stack_max = 64, stack_max = 64,
groups = groups, groups = groups,
sounds = mcl_sounds.node_sound_metal_defaults(), sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 0.7, _mcl_blast_resistance = 3.5,
_mcl_hardness = 0.7, _mcl_hardness = 0.7,
after_destruct = function(pos) after_destruct = function(pos)
-- Scan for minecarts in this pos and force them to execute their "floating" check. -- 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

@ -194,7 +194,6 @@ functions needed for the mob to work properly which contains the following:
'punch2' animations. 'punch2' animations.
'animation' holds a table containing animation names and settings for use with mesh models: '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_end' end frame of stand animation.
'stand_speed' speed of animation in frames per second. 'stand_speed' speed of animation in frames per second.
@ -220,7 +219,6 @@ functions needed for the mob to work properly which contains the following:
'die_end' 'die_end'
'die_speed' 'die_speed'
'die_loop' when set to false stops the animation looping. 'die_loop' when set to false stops the animation looping.
}
Using '_loop = false' setting will stop any of the above animations from Using '_loop = false' setting will stop any of the above animations from
looping. 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) '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 'sunlight_damage' holds the damage per second inflicted to mobs when they
are in direct sunlight 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 spawning fails due to space requirements
'glow' same as in entity definition 'glow' same as in entity definition
'child' if true, spawn mob as child 'child' if true, spawn mob as child
@ -255,12 +253,6 @@ functions needed for the mob to work properly which contains the following:
'fire_resistant' If true, the mob can't burn 'fire_resistant' If true, the mob can't burn
'fire_damage_resistant' If true the mob will not take damage when burning '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) '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 - return true to not pickup the item
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival

View File

@ -12,7 +12,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false
local node_ok = function(pos, fallback) 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) 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 local attach_at, eye_offset
@ -162,7 +162,7 @@ function mcl_mobs.attach(entity, player)
end end
function mcl_mobs.detach(player, offset) function mobs.detach(player, offset)
force_detach(player) force_detach(player)
@ -185,7 +185,7 @@ function mcl_mobs.detach(player, offset)
end 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 local rot_view = 0
@ -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 entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then if stand_anim then
mcl_mobs:set_animation(entity, stand_anim) mobs:set_animation(entity, stand_anim)
end end
return return
@ -269,7 +269,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- set moving animation -- set moving animation
if moving_anim then if moving_anim then
mcl_mobs:set_animation(entity, moving_anim) mobs:set_animation(entity, moving_anim)
end end
-- Stop! -- Stop!
@ -388,7 +388,7 @@ end
-- directional flying routine by D00Med (edited by TenPlus1) -- 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 ctrl = entity.driver:get_player_control()
local velo = entity.object:get_velocity() 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 -- change animation if stopped
if velo.x == 0 and velo.y == 0 and velo.z == 0 then 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 else
-- moving animation -- moving animation
mcl_mobs:set_animation(entity, moving_anim) mobs:set_animation(entity, moving_anim)
end end
end end

View File

@ -3,66 +3,22 @@ local get_node = minetest.get_node
local get_item_group = minetest.get_item_group local get_item_group = minetest.get_item_group
local get_node_light = minetest.get_node_light local get_node_light = minetest.get_node_light
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
local get_biome_name = minetest.get_biome_name local new_vector = vector.new
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_connected_players = minetest.get_connected_players
local minetest_get_perlin = minetest.get_perlin
local math_random = math.random local math_random = math.random
local math_floor = math.floor local get_biome_name = minetest.get_biome_name
local math_ceil = math.ceil local max = math.max
local math_cos = math.cos local get_objects_inside_radius = minetest.get_objects_inside_radius
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
local table_copy = table.copy
local table_remove = table.remove
local pairs = pairs
local dbg_spawn_attempts = 0
local dbg_spawn_succ = 0
-- range for mob count -- range for mob count
local aoc_range = 136 local aoc_range = 32
--[[
local mob_cap = { THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
monster = 70,
animal =10,
ambient =15,
water = 5, --currently unused
water_ambient = 20, --currently unused
}
--do mobs spawn?
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local noise_params = {
offset = 0,
scale = 3,
spread = {
x = 301,
y = 50,
z = 304,
},
seed = 100,
octaves = 3,
persistence = 0.5,
}
-- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
-- Also used for missing parameter
-- Please update the list when adding new biomes!
local list_of_all_biomes = {
-- underground:
underground:
"FlowerForest_underground", "FlowerForest_underground",
"JungleEdge_underground", "JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
"ColdTaiga_underground", "ColdTaiga_underground",
"IcePlains_underground", "IcePlains_underground",
"IcePlainsSpikes_underground", "IcePlainsSpikes_underground",
@ -72,10 +28,8 @@ local list_of_all_biomes = {
"JungleM_underground", "JungleM_underground",
"ExtremeHillsM_underground", "ExtremeHillsM_underground",
"JungleEdgeM_underground", "JungleEdgeM_underground",
"MangroveSwamp_underground",
-- ocean:
ocean:
"RoofedForest_ocean", "RoofedForest_ocean",
"JungleEdgeM_ocean", "JungleEdgeM_ocean",
"BirchForestM_ocean", "BirchForestM_ocean",
@ -136,18 +90,14 @@ local list_of_all_biomes = {
"BirchForestM_deep_ocean", "BirchForestM_deep_ocean",
"Taiga_deep_ocean", "Taiga_deep_ocean",
"JungleM_ocean", "JungleM_ocean",
"MangroveSwamp_ocean",
"MangroveSwamp_deep_ocean",
-- water or beach?
water or beach?
"MesaPlateauFM_sandlevel", "MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel", "MesaPlateauF_sandlevel",
"MesaBryce_sandlevel", "MesaBryce_sandlevel",
"Mesa_sandlevel", "Mesa_sandlevel",
-- beach: beach:
"FlowerForest_beach", "FlowerForest_beach",
"Forest_beach", "Forest_beach",
"StoneBeach", "StoneBeach",
@ -161,26 +111,17 @@ local list_of_all_biomes = {
"MushroomIslandShore", "MushroomIslandShore",
"JungleM_shore", "JungleM_shore",
"Jungle_shore", "Jungle_shore",
"MangroveSwamp_shore",
-- dimension biome:
dimension biome:
"Nether", "Nether",
"BasaltDelta",
"CrimsonForest",
"WarpedForest",
"SoulsandValley",
"End", "End",
-- Overworld regular: Overworld regular:
"Mesa", "Mesa",
"FlowerForest", "FlowerForest",
"Swampland", "Swampland",
"Taiga", "Taiga",
"ExtremeHills", "ExtremeHills",
"ExtremeHillsM",
"ExtremeHills+_snowtop",
"Jungle", "Jungle",
"Savanna", "Savanna",
"BirchForest", "BirchForest",
@ -199,6 +140,7 @@ local list_of_all_biomes = {
"ExtremeHills+_snowtop", "ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop", "MesaPlateauFM_grasstop",
"JungleEdgeM", "JungleEdgeM",
"ExtremeHillsM",
"JungleM", "JungleM",
"BirchForestM", "BirchForestM",
"MesaPlateauF", "MesaPlateauF",
@ -207,39 +149,39 @@ local list_of_all_biomes = {
"MesaBryce", "MesaBryce",
"JungleEdge", "JungleEdge",
"SavannaM", "SavannaM",
"MangroveSwamp", ]]--
}
-- count how many mobs are in an area
local function count_mobs(pos,r,mob_type)
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
-- count how many mobs of one type are inside an area
local count_mobs = function(pos,mobtype)
local num = 0 local num = 0
for _,l in pairs(minetest.luaentities) do local objs = get_objects_inside_radius(pos, aoc_range)
if l and l.is_mob and (mob_type == nil or l.type == mob_type) then for n = 1, #objs do
local p = l.object:get_pos() local obj = objs[n]:get_luaentity()
if p and vector_distance(p,pos) < r then if obj and obj.name and obj._cmi_is_mob then
-- count hostile mobs only
if mobtype == "hostile" then
if obj.spawn_class == "hostile" then
num = num + 1
end
-- count passive mobs only
else
num = num + 1 num = num + 1
end end
end 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 return num
end end
-- global functions -- 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 -- global function to add additional spawn checks
-- return true to stop spawning mob -- return true to stop spawning mob
end end
@ -273,72 +215,10 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
--this is where all of the spawning information is kept --this is where all of the spawning information is kept
local spawn_dictionary = {} local spawn_dictionary = {}
local summary_chance = 0
function mcl_mobs:spawn_setup(def) 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)
if not mobs_spawn then return end
if not def then --print(dump(biomes))
minetest.log("warning", "Empty mob spawn setup definition")
return
end
local name = def.name
if not name then
minetest.log("warning", "Missing mob name")
return
end
local dimension = def.dimension or "overworld"
local type_of_spawning = def.type_of_spawning or "ground"
local biomes = def.biomes or list_of_all_biomes
local min_light = def.min_light or 0
local max_light = def.max_light or (minetest.LIGHT_MAX + 1)
local chance = def.chance or 1000
local aoc = def.aoc or aoc_range
local min_height = def.min_height or mcl_mapgen.overworld.min
local max_height = def.max_height or mcl_mapgen.overworld.max
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
local check_position = def.check_position
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)
if numbers then
numbers = numbers:split(",")
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))
return
end
minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
if chance < 1 then
chance = 1
minetest.log("warning", "Chance shouldn't be less than 1 (mob name: " .. name ..")")
end
spawn_dictionary[#spawn_dictionary + 1] = {
name = name,
dimension = dimension,
type_of_spawning = type_of_spawning,
biomes = biomes,
min_light = min_light,
max_light = max_light,
chance = chance,
aoc = aoc,
min_height = min_height,
max_height = max_height,
day_toggle = day_toggle,
check_position = check_position,
on_spawn = on_spawn,
}
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)
-- Do mobs spawn at all? -- Do mobs spawn at all?
if not mobs_spawn then if not mobs_spawn then
@ -354,11 +234,184 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
aoc = tonumber(numbers[2]) or aoc aoc = tonumber(numbers[2]) or aoc
if chance == 0 then 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 return
end 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
--[[
local spawn_action
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos)
-- is mob actually registered?
if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then
minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!")
return
end
-- additional custom checks for spawning mob
if mobs:spawn_abm_check(pos, node, name) == true then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!")
return
end
-- count nearby mobs in same spawn class
local entdef = minetest.registered_entities[name]
local spawn_class = entdef and entdef.spawn_class
if not spawn_class then
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
end
local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class]
-- do not spawn if too many of same mob in area
if active_object_count_wider >= max_per_block -- large-range mob cap
or (not in_class_cap) -- spawn class mob cap
or count_mobs(pos, name) >= aoc then -- per-mob mob cap
-- too many entities
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!")
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
-- mob needs night
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!")
return
end
else
-- night time but mob wants day
if day_toggle == true then
-- mob needs day
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!")
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
-- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 24)
for n = 1, #objs do
if objs[n]:is_player() then
-- player too close
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!")
return
end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!")
return
end
-- are we spawning within height limits?
if pos.y > max_height
or pos.y < min_height then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!")
return
end
-- are light levels ok?
local light = minetest.get_node_light(pos)
if not light
or light > max_light
or light < min_light then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!")
return
end
-- do we have enough space to spawn mob?
local ent = minetest.registered_entities[name]
local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x
if width_x % 2 == 0 then
max_x = math.floor(width_x/2)
min_x = -(max_x-1)
else
max_x = math.floor(width_x/2)
min_x = -max_x
end
local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z/2)
min_z = -(max_z-1)
else
max_z = math.floor(width_z/2)
min_z = -max_z
end
local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
-- inside block
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
end
return
end
end
end
end
-- tweak X/Y/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
if on_spawn then
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end
end
local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider, name)
end
]]--
local entdef = minetest.registered_entities[name]
local spawn_class
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end end
--load information into the spawn dictionary --load information into the spawn dictionary
@ -370,34 +423,106 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
spawn_dictionary[key]["biomes"] = biomes spawn_dictionary[key]["biomes"] = biomes
spawn_dictionary[key]["min_light"] = min_light spawn_dictionary[key]["min_light"] = min_light
spawn_dictionary[key]["max_light"] = max_light spawn_dictionary[key]["max_light"] = max_light
spawn_dictionary[key]["interval"] = interval
spawn_dictionary[key]["chance"] = chance spawn_dictionary[key]["chance"] = chance
spawn_dictionary[key]["aoc"] = aoc spawn_dictionary[key]["aoc"] = aoc
spawn_dictionary[key]["min_height"] = min_height spawn_dictionary[key]["min_height"] = min_height
spawn_dictionary[key]["max_height"] = max_height spawn_dictionary[key]["max_height"] = max_height
spawn_dictionary[key]["day_toggle"] = day_toggle spawn_dictionary[key]["day_toggle"] = day_toggle
--spawn_dictionary[key]["on_spawn"] = spawn_abm_action
spawn_dictionary[key]["spawn_class"] = spawn_class
summary_chance = summary_chance + chance --[[
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = floor(max(1, chance * mobs_spawn_chance)),
catch_up = false,
action = spawn_abm_action,
})
]]--
end end
local two_pi = 2 * math.pi -- compatibility with older mob registration
local function get_next_mob_spawn_pos(pos) -- we're going to forget about this for now -j4i
local distance = math_random(25, 32) --[[
local angle = math_random() * two_pi function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
return {
x = math_round(pos.x + distance * math_cos(angle)), mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
y = pos.y, chance, active_object_count, -31000, max_height, day_toggle)
z = math_round(pos.z + distance * math_sin(angle)) end
]]--
--Don't disable this yet-j4i
-- MarkBu's spawn function
function mobs:spawn(def)
--does nothing for now
--[[
local name = def.name
local nodes = def.nodes or {"group:soil", "group:stone"}
local neighbors = def.neighbors or {"air"}
local min_light = def.min_light or 0
local max_light = def.max_light or 15
local interval = def.interval or 30
local chance = def.chance or 5000
local active_object_count = def.active_object_count or 1
local min_height = def.min_height or -31000
local max_height = def.max_height or 31000
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
]]--
end
local axis
--inner and outer part of square donut radius
local inner = 1
local outer = 65
local int = {-1,1}
local position_calculation = function(pos)
pos = vector.floor(pos)
--this is used to determine the axis buffer from the player
axis = math.random(0,1)
--cast towards the direction
if axis == 0 then --x
pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)]
pos.z = pos.z + math.random(-outer,outer)
else --z
pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)]
pos.x = pos.x + math.random(-outer,outer)
end
return(pos)
end
--[[
local decypher_limits_dictionary = {
["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max},
["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max},
["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max}
} }
end ]]--
local function decypher_limits(posy) local function decypher_limits(posy)
posy = math_floor(posy) --local min_max_table = decypher_limits_dictionary[dimension]
--return min_max_table[1],min_max_table[2]
posy = math.floor(posy)
return posy - 32, posy + 32 return posy - 32, posy + 32
end end
--a simple helper function for mob_spawn --a simple helper function for mob_spawn
local function biome_check(biome_list, biome_goal) local function biome_check(biome_list, biome_goal)
for _, data in pairs(biome_list) do for _,data in ipairs(biome_list) do
if data == biome_goal then if data == biome_goal then
return true return true
end end
@ -406,181 +531,127 @@ local function biome_check(biome_list, biome_goal)
return false return false
end end
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 spawn_check(pos,spawn_def)
if not spawn_def then return end
dbg_spawn_attempts = dbg_spawn_attempts + 1
local dimension = mcl_worlds.pos_to_dimension(pos)
local mob_type = minetest.registered_entities[spawn_def.name].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 = count_mobs(pos,aoc_range,mob_type)
local mob_count = count_mobs(pos,32,mob_type)
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 (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 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
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) then
if mob.type_of_spawning == "water" then
sp = get_water_spawn(sp)
end
o = minetest.add_entity(sp,mob.name)
if o then dbg_spawn_succ = dbg_spawn_succ + 1 end
end
end
return o
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 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},
{"group:solid", "group:water", "group:lava"}
)
if #spawning_position_list <= 0 then return end
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
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
local mob_chance = mob_library_worker_table[mob_index].chance
local step_chance = mob_chance
while step_chance < mob_chance_offset do
mob_index = mob_index + 1
mob_chance = mob_library_worker_table[mob_index].chance
step_chance = step_chance + mob_chance
end
local mob_def = mob_library_worker_table[mob_index]
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
return
end
end
if minetest.registered_entities[mob_def.name].can_spawn and not minetest.registered_entities[mob_def.name].can_spawn(pos) then
return
end
--everything is correct, spawn mob
local object
if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then
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
object = minetest.add_entity(spawning_position, mob_def.name)
end
if object then
return mob_def.on_spawn and mob_def.on_spawn(object, spawning_position)
end
end
current_summary_chance = current_summary_chance - mob_chance
table_remove(mob_library_worker_table, mob_index)
end
end
--todo mob limiting
--MAIN LOOP --MAIN LOOP
if mobs_spawn then
local timer = 0 local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime timer = timer + dtime
if timer < 10 then return end if timer >= 8 then
timer = 0 timer = 0
for _, player in pairs(get_connected_players()) do for _,player in pairs(minetest.get_connected_players()) do
local pos = player:get_pos() for i = 1,math_random(3,8) do
local dimension = mcl_worlds.pos_to_dimension(pos) repeat -- after this line each "break" means "continue"
-- ignore void and unloaded area local player_pos = player:get_pos()
if dimension ~= "void" and dimension ~= "default" then
local y_min, y_max = decypher_limits(pos.y) local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
for i = 1, math_random(1, 4) do
spawn_a_mob(pos, dimension, y_min, y_max) if dimension == "void" or dimension == "default" then
break -- ignore void and unloaded area
end
local min,max = decypher_limits(player_pos.y)
local goal_pos = position_calculation(player_pos)
local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"})
--couldn't find node
if #spawning_position_list <= 0 then
break
end
local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)]
--Prevent strange behavior/too close to player
if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then
break
end
local gotten_node = get_node(spawning_position)
local gotten_node_name = gotten_node.name
local gotten_node_def = minetest.registered_nodes[gotten_node_name]
if not gotten_node_name or not gotten_node_def or gotten_node_name == "air" then --skip air nodes
break
end
if gotten_node_def.use_texture_alpha and gotten_node_def.use_texture_alpha ~= "opaque" then
break
end --don't spawn on nonopaque nodes
local leaf = minetest.get_item_group(gotten_node_name,"leaves")
if leaf ~= 0 then
break end --don't spawn on treetops
local gotten_biome = minetest.get_biome_data(spawning_position)
if not gotten_biome then
break --skip if in unloaded area
end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
--grab random mob
local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)]
if not mob_def then
break --skip if something ridiculous happens (nil mob def)
end
--skip if not correct dimension
if mob_def.dimension ~= dimension then
break
end
--skip if not in correct biome
if not biome_check(mob_def.biomes, gotten_biome) then
break
end
--add this so mobs don't spawn inside nodes
spawning_position.y = spawning_position.y + 1
if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then
break
end
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(spawning_position)
--don't spawn if not in light limits
if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then
break
end
local is_water = get_item_group(gotten_node_name, "water") ~= 0
local is_lava = get_item_group(gotten_node_name, "lava") ~= 0
if mob_def.type_of_spawning == "ground" and is_water then
break
end
if mob_def.type_of_spawning == "ground" and is_lava then
break
end
--finally do the heavy check (for now) of mobs in area
if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then
break
end
--adjust the position for water and lava mobs
if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then
spawning_position.y = spawning_position.y - 1
end
--everything is correct, spawn mob
minetest.add_entity(spawning_position, mob_def.name)
until true --this is a safety catch
end end
end end
end end
end) end)
end end
minetest.register_chatcommand("mobstats",{
privs = { debug = true },
func = function(n,param)
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

@ -1,60 +0,0 @@
local dim = {"x", "z"}
local modpath = minetest.get_modpath(minetest.get_current_modname())
local function load_schem(filename)
local file = io.open(modpath .. "/schems/" .. filename, "r")
local data = minetest.deserialize(file:read())
file:close()
return data
end
local wither_spawn_schems = {}
for _, d in pairs(dim) do
wither_spawn_schems[d] = load_schem("wither_spawn_" .. d .. ".we")
end
local function check_schem(pos, schem)
for _, n in pairs(schem) do
if minetest.get_node(vector.add(pos, n)).name ~= n.name then
return false
end
end
return true
end
local function remove_schem(pos, schem)
for _, n in pairs(schem) do
minetest.remove_node(vector.add(pos, n))
end
end
local function wither_spawn(pos)
for _, d in pairs(dim) do
for i = 0, 2 do
local p = vector.add(pos, {x = 0, y = -2, z = 0, [d] = -i})
local schem = wither_spawn_schems[d]
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
minetest.after(0, wither_spawn, pointed.above)
end
return old_on_place(itemstack, placer, pointed)
end

View File

@ -1,4 +0,0 @@
name = mcl_wither_spawning
description = Wither Spawning for MineClone2
author = Fleckenstein
depends = mobs_mc, mcl_heads

View File

@ -1 +0,0 @@
return {{["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 0, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 1, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 1, ["x"] = 2, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 2, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}}

View File

@ -1 +0,0 @@
return {{["y"] = 0, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 2}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 1, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 2, ["param2"] = 1, ["param1"] = 15}}

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) * `mobs_mc_mushroom_brown.png` (CC0)
* “Spawn egg” textures (`mobs_mc_spawn_icon_*`) by 22i * “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 * Any other texture not mentioned here are licensed under the MIT License
## Sounds ## 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`) * 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 * 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 ### Links
* [`mobs_mc`](https://github.com/maikerumine/mobs_mc) * [`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") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:bat", { mobs:register_mob("mobs_mc:bat", {
description = S("Bat"), description = S("Bat"),
type = "animal", type = "animal",
spawn_class = "ambient", spawn_class = "ambient",
can_despawn = true, can_despawn = true,
spawn_in_group = 8,
passive = true, passive = true,
hp_min = 6, hp_min = 6,
hp_max = 6, hp_max = 6,
@ -66,7 +65,7 @@ else
end end
-- Spawn on solid blocks at or below Sea level and the selected light level -- Spawn on solid blocks at or below Sea level and the selected light level
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:bat", "mobs_mc:bat",
"overworld", "overworld",
"ground", "ground",
@ -139,9 +138,9 @@ maxlight,
20, 20,
5000, 5000,
2, 2,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.water_level-1) mobs_mc.spawn_height.water-1)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 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"), description = S("Blaze"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 3,
hp_min = 20, hp_min = 20,
hp_max = 20, hp_max = 20,
xp_min = 10, xp_min = 10,
@ -43,7 +41,7 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
reach = 2, reach = 2,
pathfinding = 1, pathfinding = 1,
drops = { drops = {
{name = "mcl_mobitems:blaze_rod", {name = mobs_mc.items.blaze_rod,
chance = 1, chance = 1,
min = 0, min = 0,
max = 1, max = 1,
@ -133,7 +131,7 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
end, end,
}) })
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:blaze", "mobs_mc:blaze",
"nether", "nether",
"ground", "ground",
@ -143,11 +141,11 @@ minetest.LIGHT_MAX+1,
30, 30,
5000, 5000,
3, 3,
mcl_vars.mg_nether_min, mobs_mc.spawn_height.nether_min,
mcl_vars.mg_nether_max) mobs_mc.spawn_height.nether_max)
-- Blaze fireball -- Blaze fireball
mcl_mobs:register_arrow("mobs_mc:blaze_fireball", { mobs:register_arrow("mobs_mc:blaze_fireball", {
visual = "sprite", visual = "sprite",
visual_size = {x = 0.3, y = 0.3}, visual_size = {x = 0.3, y = 0.3},
textures = {"mcl_fire_fire_charge.png"}, textures = {"mcl_fire_fire_charge.png"},
@ -183,7 +181,7 @@ mcl_mobs:register_arrow("mobs_mc:blaze_fireball", {
-- Node hit, make fire -- Node hit, make fire
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
if node == "air" then if node == "air" then
minetest.set_node(pos, {name = "mcl_fire:fire"}) minetest.set_node(pos, {name = mobs_mc.items.fire})
else else
if self._shot_from_dispenser and mod_target and node == "mcl_target:target_off" then 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 mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
@ -195,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) -- Set fire if node is air, or a replacable flammable node (e.g. a plant)
if crashnode.name == "air" or if crashnode.name == "air" or
(cndef and cndef.buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then (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 end
end end
}) })
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:blaze", S("Blaze"), "mobs_mc_spawn_icon_blaze.png", 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"), description = S("Chicken"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
@ -30,12 +30,12 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
makes_footstep_sound = true, makes_footstep_sound = true,
walk_velocity = 1, walk_velocity = 1,
drops = { drops = {
{name = "mcl_mobitems:chicken", {name = mobs_mc.items.chicken_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 1, max = 1,
looting = "common",}, looting = "common",},
{name = "mcl_mobitems:feather", {name = mobs_mc.items.feather,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -64,19 +64,14 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
run_start = 0, run_end = 40, run_start = 0, run_end = 40,
}, },
follow = { follow = mobs_mc.follow.chicken,
"mcl_farming:wheat_seeds",
"mcl_farming:melon_seeds",
"mcl_farming:pumpkin_seeds",
"mcl_farming:beetroot_seeds",
},
view_range = 16, view_range = 16,
fear_height = 4, fear_height = 4,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end if mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
end, end,
do_custom = function(self, dtime) do_custom = function(self, dtime)
@ -94,7 +89,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
local pos = self.object:get_pos() 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", { minetest.sound_play("mobs_mc_chicken_lay_egg", {
pos = pos, pos = pos,
@ -106,7 +101,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
}) })
--spawn --spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:chicken", "mobs_mc:chicken",
"overworld", "overworld",
"ground", "ground",
@ -122,6 +117,8 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach", "ExtremeHills_beach",
"ExtremeHillsM", "ExtremeHillsM",
"ExtremeHills+", "ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains", "Plains",
"Plains_beach", "Plains_beach",
"SunflowerPlains", "SunflowerPlains",
@ -150,8 +147,8 @@ mcl_mobs:spawn_specific(
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 17000, 30, 17000,
3, 3,
mobs_mc.water_level, mobs_mc.spawn_height.water,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 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"), "extra_mobs_spawn_icon_cod.png", 0)

View File

@ -21,12 +21,12 @@ local cow_def = {
makes_footstep_sound = true, makes_footstep_sound = true,
walk_velocity = 1, walk_velocity = 1,
drops = { drops = {
{name = "mcl_mobitems:beef", {name = mobs_mc.items.beef_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 3, max = 3,
looting = "common",}, looting = "common",},
{name = "mcl_mobitems:leather", {name = mobs_mc.items.leather,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -47,62 +47,61 @@ local cow_def = {
walk_end = 40, run_start = 0, walk_end = 40, run_start = 0,
run_end = 40, run_end = 40,
}, },
follow = mobs_mc.follow.cow,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if self.child then if self.child then
return return
end end
local item = clicker:get_wielded_item() 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() 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}) 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 room add bucket of milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name = "mcl_mobitems:milk_bucket"}) then if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket") clicker:get_inventory():add_item("main", mobs_mc.items.milk)
else else
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.5 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 end
return return
end end
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end, end,
follow = "mcl_farming:wheat_item", follow = mobs_mc.items.wheat,
view_range = 10, view_range = 10,
fear_height = 4, fear_height = 4,
} }
mcl_mobs:register_mob("mobs_mc:cow", cow_def) mobs:register_mob("mobs_mc:cow", cow_def)
-- Mooshroom -- Mooshroom
local mooshroom_def = table.copy(cow_def) local mooshroom_def = table.copy(cow_def)
mooshroom_def.description = S("Mooshroom") mooshroom_def.description = S("Mooshroom")
mooshroom_def.mesh = "mobs_mc_cow.b3d" mooshroom_def.mesh = "mobs_mc_cow.b3d"
mooshroom_def.spawn_in_group_min = 4
mooshroom_def.spawn_in_group = 8
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } } 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) mooshroom_def.on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if self.child then if self.child then
return return
end end
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
-- Use shears to get mushrooms and turn mooshroom into cow -- 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() local pos = self.object:get_pos()
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then 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 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 end
local oldyaw = self.object:get_yaw() local oldyaw = self.object:get_yaw()
@ -111,54 +110,59 @@ mooshroom_def.on_rightclick = function(self, clicker)
cow:set_yaw(oldyaw) cow:set_yaw(oldyaw)
if not minetest.is_creative_enabled(clicker:get_player_name()) then 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) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
end end
-- Use bucket to milk -- 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() 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}) 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 room, add milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name="mcl_mobitems:milk_bucket"}) then if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket") clicker:get_inventory():add_item("main", mobs_mc.items.milk)
else else
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.5 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 end
-- Use bowl to get mushroom stew -- 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() 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}) 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 room, add mushroom stew to inventory, otherwise drop as item
if inv:room_for_item("main", {name="mcl_mushrooms:mushroom_stew"}) then if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then
clicker:get_inventory():add_item("main", "mcl_mushrooms:mushroom_stew") clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew)
else else
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos.y = pos.y + 0.5 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
end end
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end end
mcl_mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
-- Spawning -- Spawning
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:cow", "mobs_mc:cow",
"overworld", "overworld",
"ground", "ground",
{ {
"flat", "flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga", "MegaTaiga",
"MegaSpruceTaiga", "MegaSpruceTaiga",
"ExtremeHills", "ExtremeHills",
"ExtremeHills_beach", "ExtremeHills_beach",
"ExtremeHillsM", "ExtremeHillsM",
"ExtremeHills+", "ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach", "StoneBeach",
"Plains", "Plains",
"Plains_beach", "Plains_beach",
@ -189,12 +193,12 @@ minetest.LIGHT_MAX+1,
30, 30,
17000, 17000,
10, 10,
mobs_mc.water_level, mobs_mc.spawn_height.water,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:mooshroom", "mobs_mc:mooshroom",
"overworld", "overworld",
"ground", "ground",
@ -207,9 +211,9 @@ minetest.LIGHT_MAX+1,
30, 30,
17000, 17000,
5, 5,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn egg -- spawn egg
mcl_mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)
mcl_mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.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", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
spawn_in_group = 1,
hp_min = 20, hp_min = 20,
hp_max = 20, hp_max = 20,
xp_min = 5, xp_min = 5,
@ -59,7 +58,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
return return
end end
local item = clicker:get_wielded_item() 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 if not minetest.is_creative_enabled(clicker:get_player_name()) then
-- Wear tool -- Wear tool
local wdef = item:get_definition() local wdef = item:get_definition()
@ -78,7 +77,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
if self._forced_explosion_countdown_timer ~= nil then if self._forced_explosion_countdown_timer ~= nil then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then 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 end
end, end,
@ -89,14 +88,14 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
if luaentity and luaentity.name:find("arrow") then if luaentity and luaentity.name:find("arrow") then
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity() 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 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
end end
end, end,
maxdrops = 2, maxdrops = 2,
drops = { drops = {
{name = "mcl_mobitems:gunpowder", {name = mobs_mc.items.gunpowder,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -104,7 +103,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
-- Head -- Head
-- TODO: Only drop if killed by charged creeper -- TODO: Only drop if killed by charged creeper
{name = "mcl_heads:creeper", {name = mobs_mc.items.head_creeper,
chance = 200, -- 0.5% chance = 200, -- 0.5%
min = 1, min = 1,
max = 1,}, max = 1,},
@ -130,7 +129,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
view_range = 16, view_range = 16,
}) })
mcl_mobs:register_mob("mobs_mc:creeper_charged", { mobs:register_mob("mobs_mc:creeper_charged", {
description = S("Creeper"), description = S("Creeper"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -181,7 +180,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
return return
end end
local item = clicker:get_wielded_item() 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 if not minetest.is_creative_enabled(clicker:get_player_name()) then
-- Wear tool -- Wear tool
local wdef = item:get_definition() local wdef = item:get_definition()
@ -200,7 +199,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
if self._forced_explosion_countdown_timer ~= nil then if self._forced_explosion_countdown_timer ~= nil then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then 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 end
end, end,
@ -211,14 +210,14 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
if luaentity and luaentity.name:find("arrow") then if luaentity and luaentity.name:find("arrow") then
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity() 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 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
end end
end, end,
maxdrops = 2, maxdrops = 2,
drops = { drops = {
{name = "mcl_mobitems:gunpowder", {name = mobs_mc.items.gunpowder,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -226,7 +225,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
-- Head -- Head
-- TODO: Only drop if killed by charged creeper -- TODO: Only drop if killed by charged creeper
{name = "mcl_heads:creeper", {name = mobs_mc.items.head_creeper,
chance = 200, -- 0.5% chance = 200, -- 0.5%
min = 1, min = 1,
max = 1,}, max = 1,},
@ -255,7 +254,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
glow = 3, glow = 3,
}) })
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:creeper", "mobs_mc:creeper",
"overworld", "overworld",
"ground", "ground",
@ -275,6 +274,7 @@ mcl_mobs:spawn_specific(
"Plains", "Plains",
"Desert", "Desert",
"ColdTaiga", "ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes", "IcePlainsSpikes",
"SunflowerPlains", "SunflowerPlains",
"IcePlains", "IcePlains",
@ -301,6 +301,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach", "ExtremeHills_beach",
"ColdTaiga_beach", "ColdTaiga_beach",
"Swampland_shore", "Swampland_shore",
"MushroomIslandShore",
"JungleM_shore", "JungleM_shore",
"Jungle_shore", "Jungle_shore",
"MesaPlateauFM_sandlevel", "MesaPlateauFM_sandlevel",
@ -339,6 +340,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean", "Forest_deep_ocean",
"JungleM_deep_ocean", "JungleM_deep_ocean",
"FlowerForest_deep_ocean", "FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean", "MegaTaiga_ocean",
"StoneBeach_deep_ocean", "StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean", "IcePlainsSpikes_deep_ocean",
@ -348,6 +350,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean", "MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean", "ExtremeHills+_deep_ocean",
"ExtremeHills_ocean", "ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean", "Forest_ocean",
"MegaTaiga_deep_ocean", "MegaTaiga_deep_ocean",
"JungleEdge_ocean", "JungleEdge_ocean",
@ -373,6 +376,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground", "RoofedForest_underground",
"Jungle_underground", "Jungle_underground",
"Swampland_underground", "Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground", "BirchForest_underground",
"Plains_underground", "Plains_underground",
"MesaPlateauF_underground", "MesaPlateauF_underground",
@ -400,8 +404,8 @@ mcl_mobs:spawn_specific(
20, 20,
16500, 16500,
2, 2,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)

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"), "extra_mobs_spawn_icon_dolphin.png", 0)

View File

@ -4,7 +4,7 @@
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:enderdragon", { mobs:register_mob("mobs_mc:enderdragon", {
description = S("Ender Dragon"), description = S("Ender Dragon"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -35,7 +35,6 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
}, },
physical = true, physical = true,
damage = 10, damage = 10,
knock_back = false,
jump = true, jump = true,
jump_height = 14, jump_height = 14,
fly = true, fly = true,
@ -99,7 +98,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
if self._initial then if self._initial then
mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000 mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = "mcl_end:dragon_egg"}) minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
end end
end end
end, end,
@ -110,7 +109,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
-- dragon fireball (projectile) -- dragon fireball (projectile)
mcl_mobs:register_arrow("mobs_mc:dragon_fireball", { mobs:register_arrow("mobs_mc:dragon_fireball", {
visual = "sprite", visual = "sprite",
visual_size = {x = 1.25, y = 1.25}, visual_size = {x = 1.25, y = 1.25},
textures = {"mobs_mc_dragon_fireball.png"}, textures = {"mobs_mc_dragon_fireball.png"},
@ -134,10 +133,10 @@ mcl_mobs:register_arrow("mobs_mc:dragon_fireball", {
-- node hit, explode -- node hit, explode
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
mcl_mobs:boom(self, pos, 2) mobs:boom(self, pos, 2)
end end
}) })
mcl_mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 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") mcl_wip.register_wip_item("mobs_mc:enderdragon")

View File

@ -48,37 +48,6 @@ local take_frequency_max = 245
local place_frequency_min = 235 local place_frequency_min = 235
local place_frequency_max = 245 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 -- Create the textures table for the enderman, depending on which kind of block
-- the enderman holds (if any). -- the enderman holds (if any).
local create_enderman_textures = function(block_type, itemstring) local create_enderman_textures = function(block_type, itemstring)
@ -100,9 +69,9 @@ local create_enderman_textures = function(block_type, itemstring)
local tiles = minetest.registered_nodes[itemstring].tiles local tiles = minetest.registered_nodes[itemstring].tiles
local textures = {} local textures = {}
local last local last
if block_texture_overrides[itemstring] then if mobs_mc.enderman_block_texture_overrides[itemstring] then
-- Texture override available? Use these instead! -- Texture override available? Use these instead!
textures = block_texture_overrides[itemstring] textures = mobs_mc.enderman_block_texture_overrides[itemstring]
else else
-- Extract the texture names -- Extract the texture names
for i = 1, 6 do for i = 1, 6 do
@ -219,9 +188,8 @@ local select_enderman_animation = function(animation_type)
end end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local spawners = {}
mcl_mobs:register_mob("mobs_mc:enderman", { mobs:register_mob("mobs_mc:enderman", {
description = S("Enderman"), description = S("Enderman"),
type = "monster", type = "monster",
spawn_class = "passive", spawn_class = "passive",
@ -250,7 +218,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
damage = 7, damage = 7,
reach = 2, reach = 2,
drops = { drops = {
{name = "mcl_throwing:ender_pearl", {name = mobs_mc.items.ender_pearl,
chance = 1, chance = 1,
min = 0, min = 0,
max = 1, max = 1,
@ -258,48 +226,23 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
}, },
animation = select_enderman_animation("normal"), animation = select_enderman_animation("normal"),
_taken_node = "", _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) do_custom = function(self, dtime)
-- PARTICLE BEHAVIOUR HERE. -- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos() local enderpos = self.object:get_pos()
if self._particle_timer and self._particle_timer >= 1 then local chanceOfParticle = math.random(0, 1)
for _,player in pairs(minetest.get_connected_players()) do if chanceOfParticle == 1 then
if not spawners[player] then spawners[player] = {} end minetest.add_particle({
local dst = vector.distance(player:get_pos(),enderpos) 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},
if dst < 128 and not spawners[player][self.object] then velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)},
self._particle_timer = 0 acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)},
spawners[player][self.object] = minetest.add_particlespawner({ expirationtime = math.random(),
amount = 5, size = math.random(),
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, collisiondetection = true,
vertical = false, vertical = false,
time = 0,
texture = "mcl_portals_particle"..math.random(1, 5)..".png", texture = "mcl_portals_particle"..math.random(1, 5)..".png",
attached = self.object,
playername = player:get_player_name(),
}) })
elseif dst > 128 and spawners[player][self.object] then
minetest.delete_particlespawner(spawners[player][self.object])
spawners[player][self.object] = nil
end end
end
elseif not self._particle_timer then
self._particle_timer = 0
end
self._particle_timer = self._particle_timer + dtime
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
enderpos = self.object:get_pos()
local dim = mcl_worlds.pos_to_dimension(enderpos) local dim = mcl_worlds.pos_to_dimension(enderpos)
if dim == "overworld" then if dim == "overworld" then
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
@ -335,6 +278,10 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
else return end else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
if self.state == "attack" then 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 if self.attack then
local target = self.attack local target = self.attack
local pos = target:get_pos() local pos = target:get_pos()
@ -344,15 +291,11 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
end end
end end
end end
else --if not attacking try to tp to the dark --end
if minetest.get_node_light(enderpos) > minetest.LIGHT_MAX then
self:teleport(nil)
end
end end
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE. -- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby. -- Check for arrows and people nearby.
local enderpos = self.object:get_pos()
enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5 enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2) local objs = minetest.get_objects_inside_radius(enderpos, 2)
for n = 1, #objs do for n = 1, #objs do
@ -445,7 +388,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
self._take_place_timer = 0 self._take_place_timer = 0
self._next_take_place_time = math.random(place_frequency_min, place_frequency_max) self._next_take_place_time = math.random(place_frequency_min, place_frequency_max)
local pos = self.object:get_pos() 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 if #takable_nodes >= 1 then
local r = pr:next(1, #takable_nodes) local r = pr:next(1, #takable_nodes)
local take_pos = takable_nodes[r] local take_pos = takable_nodes[r]
@ -455,7 +398,11 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
minetest.remove_node(take_pos) minetest.remove_node(take_pos)
local dug = minetest.get_node_or_nil(take_pos) local dug = minetest.get_node_or_nil(take_pos)
if dug and dug.name == "air" then 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 self._taken_node = node.name
end
local def = minetest.registered_nodes[self._taken_node] local def = minetest.registered_nodes[self._taken_node]
-- Update animation and texture accordingly (adds visibly carried block) -- Update animation and texture accordingly (adds visibly carried block)
local block_type local block_type
@ -484,7 +431,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
self.base_texture = create_enderman_textures(block_type, self._taken_node) self.base_texture = create_enderman_textures(block_type, self._taken_node)
self.object:set_properties({ textures = self.base_texture }) self.object:set_properties({ textures = self.base_texture })
self.animation = select_enderman_animation("block") 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 if def.sounds and def.sounds.dug then
minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true) minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true)
end end
@ -507,7 +454,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
local def = minetest.registered_nodes[self._taken_node] local def = minetest.registered_nodes[self._taken_node]
-- Update animation accordingly (removes visible block) -- Update animation accordingly (removes visible block)
self.animation = select_enderman_animation("normal") 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 if def.sounds and def.sounds.place then
minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true) minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true)
end end
@ -616,16 +563,9 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
attack_type = "dogfight", attack_type = "dogfight",
}) })
minetest.register_on_leaveplayer(function(player)
for _,s in pairs(spawners[player]) do
minetest.delete_particlespawner(s)
end
spawners[player] = nil
end)
-- End spawn -- End spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:enderman", "mobs_mc:enderman",
"end", "end",
"ground", "ground",
@ -637,10 +577,10 @@ minetest.LIGHT_MAX+1,
30, 30,
3000, 3000,
12, 12,
mcl_vars.mg_end_min, mobs_mc.spawn_height.end_min,
mcl_vars.mg_end_max) mobs_mc.spawn_height.end_max)
-- Overworld spawn -- Overworld spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:enderman", "mobs_mc:enderman",
"overworld", "overworld",
"ground", "ground",
@ -660,6 +600,7 @@ mcl_mobs:spawn_specific(
"Plains", "Plains",
"Desert", "Desert",
"ColdTaiga", "ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes", "IcePlainsSpikes",
"SunflowerPlains", "SunflowerPlains",
"IcePlains", "IcePlains",
@ -686,6 +627,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach", "ExtremeHills_beach",
"ColdTaiga_beach", "ColdTaiga_beach",
"Swampland_shore", "Swampland_shore",
"MushroomIslandShore",
"JungleM_shore", "JungleM_shore",
"Jungle_shore", "Jungle_shore",
"MesaPlateauFM_sandlevel", "MesaPlateauFM_sandlevel",
@ -724,6 +666,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean", "Forest_deep_ocean",
"JungleM_deep_ocean", "JungleM_deep_ocean",
"FlowerForest_deep_ocean", "FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean", "MegaTaiga_ocean",
"StoneBeach_deep_ocean", "StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean", "IcePlainsSpikes_deep_ocean",
@ -733,6 +676,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean", "MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean", "ExtremeHills+_deep_ocean",
"ExtremeHills_ocean", "ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean", "Forest_ocean",
"MegaTaiga_deep_ocean", "MegaTaiga_deep_ocean",
"JungleEdge_ocean", "JungleEdge_ocean",
@ -758,6 +702,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground", "RoofedForest_underground",
"Jungle_underground", "Jungle_underground",
"Swampland_underground", "Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground", "BirchForest_underground",
"Plains_underground", "Plains_underground",
"MesaPlateauF_underground", "MesaPlateauF_underground",
@ -785,41 +730,24 @@ mcl_mobs:spawn_specific(
30, 30,
19000, 19000,
2, 2,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- Nether spawn (rare) -- Nether spawn (rare)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:enderman", "mobs_mc:enderman",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"SoulsandVall3ey",
}, },
0, 0,
11, 7,
30, 30,
27500, 27500,
4, 4,
mcl_vars.mg_nether_min, mobs_mc.spawn_height.nether_min,
mcl_vars.mg_nether_max) mobs_mc.spawn_height.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)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 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") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:endermite", { mobs:register_mob("mobs_mc:endermite", {
description = S("Endermite"), description = S("Endermite"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -38,4 +38,4 @@ mcl_mobs:register_mob("mobs_mc:endermite", {
reach = 1, reach = 1,
}) })
mcl_mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 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"), description = S("Ghast"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -23,7 +23,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
collisionbox = {-2, 5, -2, 2, 9, 2}, collisionbox = {-2, 5, -2, 2, 9, 2},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_ghast.b3d", mesh = "mobs_mc_ghast.b3d",
spawn_in_group = 1,
textures = { textures = {
{"mobs_mc_ghast.png"}, {"mobs_mc_ghast.png"},
}, },
@ -40,8 +39,8 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
walk_velocity = 1.6, walk_velocity = 1.6,
run_velocity = 3.2, run_velocity = 3.2,
drops = { drops = {
{name = "mcl_mobitems:gunpowder", chance = 1, min = 0, max = 2, looting = "common"}, {name = mobs_mc.items.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.ghast_tear, chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true},
}, },
animation = { animation = {
stand_speed = 50, walk_speed = 50, run_speed = 50, stand_speed = 50, walk_speed = 50, run_speed = 50,
@ -65,14 +64,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
makes_footstep_sound = false, makes_footstep_sound = false,
instant_death = true, instant_death = true,
fire_resistant = 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) do_custom = function(self)
if self.firing == true then if self.firing == true then
self.base_texture = {"mobs_mc_ghast_firing.png"} 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", "mobs_mc:ghast",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"SoulsandValley",
"BasaltDelta",
}, },
0, 0,
7, minetest.LIGHT_MAX+1,
30, 30,
72000, 18000,
2, 2,
mcl_vars.mg_nether_min, mobs_mc.spawn_height.nether_min,
mcl_vars.mg_nether_max) mobs_mc.spawn_height.nether_max)
-- fireball (projectile) -- fireball (projectile)
mcl_mobs:register_arrow("mobs_mc:fireball", { mobs:register_arrow("mobs_mc:fireball", {
visual = "sprite", visual = "sprite",
visual_size = {x = 1, y = 1}, visual_size = {x = 1, y = 1},
textures = {"mcl_fire_fire_charge.png"}, textures = {"mcl_fire_fire_charge.png"},
@ -116,12 +105,7 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 6}, damage_groups = {fleshy = 6},
}, nil) }, nil)
local p = self.object:get_pos() mobs:boom(self, self.object:get_pos(), 1, true)
if p then
mcl_mobs:boom(self, p, 1, true)
else
mcl_mobs:boom(self, player:get_pos(), 1, true)
end
end, end,
hit_mob = function(self, mob) hit_mob = function(self, mob)
@ -129,11 +113,11 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 6}, damage_groups = {fleshy = 6},
}, nil) }, nil)
mcl_mobs:boom(self, self.object:get_pos(), 1, true) mobs:boom(self, self.object:get_pos(), 1, true)
end, end,
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
mcl_mobs:boom(self, pos, 1, true) mobs:boom(self, pos, 1, true)
end end
}) })
@ -141,4 +125,4 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0) mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0)

View File

@ -4,12 +4,10 @@
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:guardian", { mobs:register_mob("mobs_mc:guardian", {
description = S("Guardian"), description = S("Guardian"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 4,
hp_min = 30, hp_min = 30,
hp_max = 30, hp_max = 30,
xp_min = 10, xp_min = 10,
@ -46,7 +44,7 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
}, },
drops = { drops = {
-- Greatly increased amounts of prismarine -- Greatly increased amounts of prismarine
{name = "mcl_ocean:prismarine_shard", {name = mobs_mc.items.prismarine_shard,
chance = 1, chance = 1,
min = 0, min = 0,
max = 32, max = 32,
@ -55,37 +53,37 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
-- The following drops are approximations -- The following drops are approximations
-- Fish / prismarine crystal -- Fish / prismarine crystal
{name = "mcl_fishing:fish_raw", {name = mobs_mc.items.fish_raw,
chance = 4, chance = 4,
min = 1, min = 1,
max = 1, max = 1,
looting = "common",}, looting = "common",},
{name = "mcl_ocean:prismarine_crystals", {name = mobs_mc.items.prismarine_crystals,
chance = 4, chance = 4,
min = 1, min = 1,
max = 2, max = 2,
looting = "common",}, looting = "common",},
-- Rare drop: fish -- Rare drop: fish
{name = "mcl_fishing:fish_raw", {name = mobs_mc.items.fish_raw,
chance = 160, -- 2.5% / 4 chance = 160, -- 2.5% / 4
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.0025,}, looting_factor = 0.0025,},
{name = "mcl_fishing:salmon_raw", {name = mobs_mc.items.salmon_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.0025,}, looting_factor = 0.0025,},
{name = "mcl_fishing:clownfish_raw", {name = mobs_mc.items.clownfish_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.0025,}, looting_factor = 0.0025,},
{name = "mcl_fishing:pufferfish_raw", {name = mobs_mc.items.pufferfish_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
@ -94,14 +92,14 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
}, },
fly = true, fly = true,
makes_footstep_sound = false, 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, jump = false,
view_range = 16, view_range = 16,
}) })
-- Spawning disabled due to size issues -- Spawning disabled due to size issues
-- TODO: Re-enable spawning -- 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 -- spawn eggs
mcl_mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 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") 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"), description = S("Elder Guardian"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -49,51 +49,51 @@ mcl_mobs:register_mob("mobs_mc:guardian_elder", {
-- TODO: Reduce # of drops when ocean monument is ready. -- TODO: Reduce # of drops when ocean monument is ready.
-- Greatly increased amounts of prismarine -- Greatly increased amounts of prismarine
{name = "mcl_ocean:prismarine_shard", {name = mobs_mc.items.prismarine_shard,
chance = 1, chance = 1,
min = 1, min = 1,
max = 64, max = 64,
looting = "common",}, looting = "common",},
-- TODO: Only drop if killed by player -- TODO: Only drop if killed by player
{name = "mcl_sponges:sponge_wet", {name = mobs_mc.items.wet_sponge,
chance = 1, chance = 1,
min = 1, min = 1,
max = 1,}, max = 1,},
-- The following drops are approximations -- The following drops are approximations
-- Fish / prismarine crystal -- Fish / prismarine crystal
{name = "mcl_fishing:fish_raw", {name = mobs_mc.items.fish_raw,
chance = 4, chance = 4,
min = 1, min = 1,
max = 1, max = 1,
looting = "common",}, looting = "common",},
{name = "mcl_ocean:prismarine_crystals", {name = mobs_mc.items.prismarine_crystals,
chance = 1, chance = 1,
min = 1, min = 1,
max = 10, max = 10,
looting = "common",}, looting = "common",},
-- Rare drop: fish -- Rare drop: fish
{name = "mcl_fishing:fish_raw", {name = mobs_mc.items.fish_raw,
chance = 160, -- 2.5% / 4 chance = 160, -- 2.5% / 4
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.01 / 4,}, looting_factor = 0.01 / 4,},
{name = "mcl_fishing:salmon_raw", {name = mobs_mc.items.salmon_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.01 / 4,}, looting_factor = 0.01 / 4,},
{name = "mcl_fishing:clownfish_raw", {name = mobs_mc.items.clownfish_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
looting = "rare", looting = "rare",
looting_factor = 0.01 / 4,}, looting_factor = 0.01 / 4,},
{name = "mcl_fishing:pufferfish_raw", {name = mobs_mc.items.pufferfish_raw,
chance = 160, chance = 160,
min = 1, min = 1,
max = 1, max = 1,
@ -102,15 +102,15 @@ mcl_mobs:register_mob("mobs_mc:guardian_elder", {
}, },
fly = true, fly = true,
makes_footstep_sound = false, 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, jump = false,
view_range = 16, view_range = 16,
}) })
-- Spawning disabled due to size issues <- what do you mean? -j4i -- Spawning disabled due to size issues <- what do you mean? -j4i
-- TODO: Re-enable spawning -- 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 -- spawn eggs
mcl_mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0) mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0)

View File

@ -81,27 +81,11 @@ for b=1, #horse_base do
end end
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 -- Horse
local horse = { local horse = {
description = S("Horse"), description = S("Horse"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 6,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_horse.b3d", mesh = "mobs_mc_horse.b3d",
visual_size = {x=3.0, y=3.0}, visual_size = {x=3.0, y=3.0},
@ -130,14 +114,7 @@ local horse = {
fly = false, fly = false,
walk_chance = 60, walk_chance = 60,
view_range = 16, view_range = 16,
follow = { follow = mobs_mc.follow.horse,
"mcl_core:apple",
"mcl_core:sugar",
"mcl_farming:wheat_item",
"mcl_farming:hay_block",
"mcl_core:apple_gold",
"mcl_farming:carrot_item_gold",
},
passive = true, passive = true,
hp_min = 15, hp_min = 15,
hp_max = 30, hp_max = 30,
@ -148,13 +125,13 @@ local horse = {
jump = true, jump = true,
jump_height = 5.75, -- can clear 2.5 blocks jump_height = 5.75, -- can clear 2.5 blocks
drops = { drops = {
{name = "mcl_mobitems:leather", {name = mobs_mc.items.leather,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
looting = "common",}, looting = "common",},
}, },
on_spawn = update_textures,
do_custom = function(self, dtime) do_custom = function(self, dtime)
-- set needed values if not already present -- set needed values if not already present
@ -184,7 +161,7 @@ local horse = {
-- Some weird human is riding. Buck them off? -- Some weird human is riding. Buck them off?
if self.driver and not self.tamed and self.buck_off_time <= 0 then if self.driver and not self.tamed and self.buck_off_time <= 0 then
if math.random() < 0.2 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 -- TODO bucking animation
else else
-- Nah, can't be bothered. Think about it again in one second -- Nah, can't be bothered. Think about it again in one second
@ -205,7 +182,7 @@ local horse = {
-- if driver present and horse has a saddle allow control of horse -- if driver present and horse has a saddle allow control of horse
if self.driver and self._saddle then 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 return false -- skip rest of mob functions
end end
@ -217,11 +194,11 @@ local horse = {
-- drop saddle when horse is killed while riding -- drop saddle when horse is killed while riding
if self._saddle then if self._saddle then
minetest.add_item(pos, "mcl_mobitems:saddle") minetest.add_item(pos, mobs_mc.items.saddle)
end end
-- also detach from horse properly -- also detach from horse properly
if self.driver then 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
end, end,
@ -245,20 +222,20 @@ local horse = {
-- Feeding, intentionally not using mobs:feed_tame because horse taming is -- Feeding, intentionally not using mobs:feed_tame because horse taming is
-- different and more complicated -- different and more complicated
if (iname == "mcl_core:sugar") then if (iname == mobs_mc.items.sugar) then
temper_increase = 3 temper_increase = 3
elseif (iname == "mcl_farming:wheat_item") then elseif (iname == mobs_mc.items.wheat) then
temper_increase = 3 temper_increase = 3
elseif (iname == "mcl_core:apple") then elseif (iname == mobs_mc.items.apple) then
temper_increase = 3 temper_increase = 3
elseif (iname == "mcl_farming:carrot_item_gold") then elseif (iname == mobs_mc.items.golden_carrot) then
temper_increase = 5 temper_increase = 5
elseif (iname == "mcl_core:apple_gold") then elseif (iname == mobs_mc.items.golden_apple) then
temper_increase = 10 temper_increase = 10
-- Trying to ride -- Trying to ride
elseif not self.driver then elseif not self.driver then
self.object:set_properties({stepheight = 1.1}) 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? self.buck_off_time = 40 -- TODO how long does it take in minecraft?
if self.temper > 100 then if self.temper > 100 then
self.tamed = true -- NOTE taming can only be finished by riding the horse self.tamed = true -- NOTE taming can only be finished by riding the horse
@ -270,7 +247,7 @@ local horse = {
-- Clicking on the horse while riding ==> unmount -- Clicking on the horse while riding ==> unmount
elseif self.driver and self.driver == clicker then 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 end
-- If nothing happened temper_increase = 0 and addition does nothing -- If nothing happened temper_increase = 0 and addition does nothing
@ -281,31 +258,31 @@ local horse = {
if can_breed(self.name) then if can_breed(self.name) then
-- Breed horse with golden apple or golden carrot -- 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 heal = 10
elseif (iname == "mcl_farming:carrot_item_gold") then elseif (iname == mobs_mc.items.golden_carrot) then
heal = 4 heal = 4
end 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 return
end end
end end
-- Feed with anything else -- Feed with anything else
-- TODO heal amounts don't work -- TODO heal amounts don't work
if (iname == "mcl_core:sugar") then if (iname == mobs_mc.items.sugar) then
heal = 1 heal = 1
elseif (iname == "mcl_farming:wheat_item") then elseif (iname == mobs_mc.items.wheat) then
heal = 2 heal = 2
elseif (iname == "mcl_core:apple") then elseif (iname == mobs_mc.items.apple) then
heal = 3 heal = 3
elseif (iname == "mcl_farming:hay_block") then elseif (iname == mobs_mc.items.hay_bale) then
heal = 20 heal = 20
end 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 return
end end
if mcl_mobs:protect(self, clicker) then if mobs:protect(self, clicker) then
return return
end end
@ -317,11 +294,11 @@ local horse = {
-- detatch player already riding horse -- detatch player already riding horse
if self.driver and clicker == self.driver then 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 -- Put on saddle if tamed
elseif not self.driver and not self._saddle 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 -- Put on saddle and take saddle from player's inventory
local w = clicker:get_wielded_item() local w = clicker:get_wielded_item()
@ -378,18 +355,18 @@ local horse = {
elseif not self.driver and self._saddle then elseif not self.driver and self._saddle then
self.object:set_properties({stepheight = 1.1}) self.object:set_properties({stepheight = 1.1})
mcl_mobs.attach(self, clicker) mobs.attach(self, clicker)
-- Used to capture horse -- Used to capture horse
elseif not self.driver and iname ~= "" then 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 end
end, end,
on_breed = function(parent1, parent2) on_breed = function(parent1, parent2)
local pos = parent1.object:get_pos() 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 if child then
local ent_c = child:get_luaentity() local ent_c = child:get_luaentity()
local p = math.random(1, 2) local p = math.random(1, 2)
@ -438,7 +415,7 @@ local horse = {
end, end,
} }
mcl_mobs:register_mob("mobs_mc:horse", horse) mobs:register_mob("mobs_mc:horse", horse)
-- Skeleton horse -- Skeleton horse
local skeleton_horse = table.copy(horse) local skeleton_horse = table.copy(horse)
@ -447,7 +424,7 @@ skeleton_horse.breath_max = -1
skeleton_horse.armor = {undead = 100, fleshy = 100} skeleton_horse.armor = {undead = 100, fleshy = 100}
skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}} skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}}
skeleton_horse.drops = { skeleton_horse.drops = {
{name = "mcl_mobitems:bone", {name = mobs_mc.items.bone,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2,}, max = 2,},
@ -461,7 +438,7 @@ skeleton_horse.sounds = {
distance = 16, distance = 16,
} }
skeleton_horse.harmed_by_heal = true 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 -- Zombie horse
local zombie_horse = table.copy(horse) local zombie_horse = table.copy(horse)
@ -470,7 +447,7 @@ zombie_horse.breath_max = -1
zombie_horse.armor = {undead = 100, fleshy = 100} zombie_horse.armor = {undead = 100, fleshy = 100}
zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}} zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}}
zombie_horse.drops = { zombie_horse.drops = {
{name = "mcl_mobitems:rotten_flesh", {name = mobs_mc.items.rotten_flesh,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2,}, max = 2,},
@ -485,15 +462,13 @@ zombie_horse.sounds = {
distance = 16, distance = 16,
} }
zombie_horse.harmed_by_heal = true 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 -- Donkey
local d = 0.86 -- donkey scale local d = 0.86 -- donkey scale
local donkey = table.copy(horse) local donkey = table.copy(horse)
donkey.description = S("Donkey") donkey.description = S("Donkey")
donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}} donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}}
donkey.spawn_in_group = 3
donkey.spawn_in_group_min = 1
donkey.animation = { donkey.animation = {
speed_normal = 25, speed_normal = 25,
stand_start = 0, stand_end = 0, stand_start = 0, stand_end = 0,
@ -518,7 +493,7 @@ donkey.collisionbox = {
donkey.jump = true donkey.jump = true
donkey.jump_height = 3.75 -- can clear 1 block height donkey.jump_height = 3.75 -- can clear 1 block height
mcl_mobs:register_mob("mobs_mc:donkey", donkey) mobs:register_mob("mobs_mc:donkey", donkey)
-- Mule -- Mule
local m = 0.94 local m = 0.94
@ -536,59 +511,84 @@ mule.collisionbox = {
horse.collisionbox[5] * m, horse.collisionbox[5] * m,
horse.collisionbox[6] * m, horse.collisionbox[6] * m,
} }
mcl_mobs:register_mob("mobs_mc:mule", mule) mobs:register_mob("mobs_mc:mule", mule)
--=========================== --===========================
--Spawn Function --Spawn Function
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:horse", "mobs_mc:horse",
"overworld", "overworld",
"ground", "ground",
{ {
"flat", "flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains", "Plains",
"Plains_beach", "Plains_beach",
"SunflowerPlains", "SunflowerPlains",
"Taiga",
"Taiga_beach",
"Forest",
"Forest_beach",
"FlowerForest",
"FlowerForest_beach",
"BirchForest",
"BirchForestM",
"RoofedForest",
"Savanna", "Savanna",
"Savanna_beach", "Savanna_beach",
"SavannaM", "SavannaM",
"Savanna_beach", "Jungle",
"Plains_beach", "Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge",
"JungleEdgeM",
"Swampland",
"Swampland_shore"
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
4, 4,
mobs_mc.water_level+3, mobs_mc.spawn_height.water+3,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:donkey", "mobs_mc:donkey",
"overworld", "overworld",
"ground", "ground",
{ {
"flat", "Mesa",
"Plains", "MesaPlateauFM_grasstop",
"Plains_beach", "MesaPlateauF",
"SunflowerPlains", "MesaPlateauFM",
"Savanna", "MesaPlateauF_grasstop",
"Savanna_beach", "MesaBryce",
"SavannaM",
"Savanna_beach",
"Plains_beach",
}, },
9, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
4, 4,
mobs_mc.water_level+3, mobs_mc.spawn_height.water+3,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
mcl_mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.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:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
mcl_mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
mcl_mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)

View File

@ -2,100 +2,45 @@
--maikerumine --maikerumine
--made for MC like Survival game --made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes --License for code WTFPL and otherwise stated in readmes
local path = minetest.get_modpath("mobs_mc")
if not minetest.get_modpath("mobs_mc_gameconfig") then
mobs_mc = {} mobs_mc = {}
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 end
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and -- For utility functions
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1. mobs_mc.tools = {}
Larger mobs might have space problems after teleportation.
* dist: Minimum required distance from owner to teleport. Default: 12 -- This function checks if the item ID has been overwritten and returns true if it is unchanged
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]] if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override and mobs_mc.override.items then
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval) mobs_mc.is_item_variable_overridden = function(id)
return function(self, dtime) return mobs_mc.override.items[id] == nil
-- No teleportation if no owner or if sitting
if not self.owner or self.order == "sit" then
return
end end
if not teleport_check_interval then else
teleport_check_interval = 4 -- No items are overwritten, so always return true
end mobs_mc.is_item_variable_overridden = function(id)
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
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 return true
end end
end
mobs_mc.shears_wear = 276 --MOB ITEMS SELECTOR SWITCH
mobs_mc.water_level = tonumber(minetest.settings:get("water_level")) or 0 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 -- Animals
local path = minetest.get_modpath("mobs_mc")
dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad
dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S 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 -- NPCs
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i 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 -- 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_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_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 dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i
@ -143,8 +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 .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
dofile(path .. "/vex.lua") -- KrupnoPavel dofile(path .. "/vex.lua") -- KrupnoPavel
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
--NOTES:
dofile(path .. "/cod.lua") --
dofile(path .. "/salmon.lua") --[[
dofile(path .. "/tropical_fish.lua") 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
dofile(path .. "/dolphin.lua") #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 --################### IRON GOLEM
--################### --###################
local etime = 0
mcl_mobs:register_mob("mobs_mc:iron_golem", {
mobs:register_mob("mobs_mc:iron_golem", {
description = S("Iron Golem"), description = S("Iron Golem"),
type = "npc", type = "npc",
spawn_class = "passive", spawn_class = "passive",
@ -37,37 +37,16 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
run_velocity = 1.2, run_velocity = 1.2,
-- Approximation -- Approximation
damage = 14, damage = 14,
knock_back = false,
reach = 3, reach = 3,
group_attack = true, group_attack = true,
attacks_monsters = true, attacks_monsters = true,
attack_type = "dogfight", attack_type = "dogfight",
_got_poppy = false,
pick_up = {"mcl_flowers:poppy"},
on_pick_up = function(self,n)
if n.itemstring:find("mcl_flowers:poppy") then
if not self._got_poppy then
self._got_poppy=true
return
end
return true
end
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 = { drops = {
{name = "mcl_core:iron_ingot", {name = mobs_mc.items.iron_ingot,
chance = 1, chance = 1,
min = 3, min = 3,
max = 5,}, max = 5,},
{name = "mcl_flowers:poppy", {name = mobs_mc.items.poppy,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2,}, max = 2,},
@ -81,19 +60,11 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
punch_start = 40, punch_end = 50, punch_start = 40, punch_end = 50,
}, },
jump = true, 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 -- spawn eggs
mcl_mobs:register_egg("mobs_mc:iron_golem", S("Iron Golem"), "mobs_mc_spawn_icon_iron_golem.png", 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 is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function of the node.
@ -108,7 +79,7 @@ I = Iron block
. = Air . = Air
]] ]]
function mobs_mc.check_iron_golem_summon(pos) mobs_mc.tools.check_iron_golem_summon = function(pos)
local checks = { local checks = {
-- These are the possible placement patterns, with offset from the pumpkin block. -- 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) -- These tables include the positions of the iron blocks (1-4) and air blocks (5-8)
@ -166,7 +137,7 @@ function mobs_mc.check_iron_golem_summon(pos)
for i=1, 4 do for i=1, 4 do
local cpos = vector.add(pos, checks[c][i]) local cpos = vector.add(pos, checks[c][i])
local node = minetest.get_node(cpos) local node = minetest.get_node(cpos)
if node.name ~= "mcl_core:ironblock" then if node.name ~= mobs_mc.items.iron_block then
ok = false ok = false
break break
end end

View File

@ -24,21 +24,15 @@ local carpets = {
unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" }, unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" },
} }
mcl_mobs:register_mob("mobs_mc:llama", { mobs:register_mob("mobs_mc:llama", {
description = S("Llama"), description = S("Llama"),
type = "animal", type = "animal",
spawn_class = "passive", 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,
hp_min = 15, hp_min = 15,
hp_max = 30, hp_max = 30,
xp_min = 1, xp_min = 1,
xp_max = 3, xp_max = 3,
passive = false,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45}, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_llama.b3d", mesh = "mobs_mc_llama.b3d",
@ -48,16 +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_gray.png"},
{"blank.png", "blank.png", "mobs_mc_llama_white.png"}, {"blank.png", "blank.png", "mobs_mc_llama_white.png"},
{"blank.png", "blank.png", "mobs_mc_llama.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}, visual_size = {x=3, y=3},
makes_footstep_sound = true, makes_footstep_sound = true,
runaway = false, runaway = true,
walk_velocity = 1, walk_velocity = 1,
run_velocity = 4.4, run_velocity = 4.4,
follow_velocity = 4.4, follow_velocity = 4.4,
floats = 1, floats = 1,
drops = { drops = {
{name = "mcl_mobitems:leather", {name = mobs_mc.items.leather,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -88,7 +83,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
look_start = 78, look_start = 78,
look_end = 108, look_end = 108,
}, },
follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" }, follow = mobs_mc.follow.llama,
view_range = 16, view_range = 16,
do_custom = function(self, dtime) do_custom = function(self, dtime)
@ -107,7 +102,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
-- if driver present allow control of llama -- if driver present allow control of llama
if self.driver then 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 return false -- skip rest of mob functions
end end
@ -119,7 +114,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
-- detach from llama properly -- detach from llama properly
if self.driver then 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
end, end,
@ -132,19 +127,20 @@ mcl_mobs:register_mob("mobs_mc:llama", {
end end
local item = clicker:get_wielded_item() 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 -- Breed with hay bale
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, false) then return end
else else
-- Feed with anything 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 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 -- 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 if self.tamed and not self.child and self.owner == clicker:get_player_name() then
-- Place carpet -- 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 if minetest.get_item_group(item:get_name(), "carpet") == 1 and not self.carpet then
for group, carpetdata in pairs(carpets) do for group, carpetdata in pairs(carpets) do
if minetest.get_item_group(item:get_name(), group) == 1 then if minetest.get_item_group(item:get_name(), group) == 1 then
@ -161,7 +157,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
}) })
self.carpet = item:get_name() self.carpet = item:get_name()
self.drops = { self.drops = {
{name = "mcl_mobitems:leather", {name = mobs_mc.items.leather,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2,}, max = 2,},
@ -174,25 +170,28 @@ mcl_mobs:register_mob("mobs_mc:llama", {
end end
end end
end end
]]
-- detatch player already riding llama -- detatch player already riding llama
if self.driver and clicker == self.driver then 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 -- attach player to llama
elseif not self.driver then elseif not self.driver then
self.object:set_properties({stepheight = 1.1}) self.object:set_properties({stepheight = 1.1})
mcl_mobs.attach(self, clicker) mobs.attach(self, clicker)
end end
-- Used to capture llama -- Used to capture llama
elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" 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, end,
--[[
TODO: Enable this code when carpet textures arrived.
on_breed = function(parent1, parent2) on_breed = function(parent1, parent2)
-- When breeding, make sure the child has no carpet -- When breeding, make sure the child has no carpet
local pos = parent1.object:get_pos() local pos = parent1.object:get_pos()
@ -202,7 +201,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
else else
parent = parent2 parent = parent2
end end
child = mcl_mobs:spawn_child(pos, parent.name) child = mobs:spawn_child(pos, parent.name)
if child then if child then
local ent_c = child:get_luaentity() local ent_c = child:get_luaentity()
ent_c.base_texture = table.copy(ent_c.base_texture) ent_c.base_texture = table.copy(ent_c.base_texture)
@ -214,57 +213,36 @@ mcl_mobs:register_mob("mobs_mc:llama", {
return false return false
end end
end, end,
]]
}) })
-- 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)
mob:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 1},
}, nil)
end,
hit_node = function(self, pos, node)
end
})
--spawn --spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:llama", "mobs_mc:llama",
"overworld", "overworld",
"ground", "ground",
{ {
"Savanna", "Mesa",
"SavannaM", "MesaPlateauFM_grasstop",
"SavannaM_beach", "MesaPlateauF",
"Savanna_beach", "MesaPlateauFM",
"Savanna_ocean", "MesaPlateauF_grasstop",
"MesaBryce",
"Jungle",
"Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge", "JungleEdge",
"JungleEdgeM", "JungleEdgeM",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
5, 5,
mobs_mc.water_level+15, mobs_mc.spawn_height.water+15,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 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 # 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 Agent=Akteur
Bat=Fledermaus Bat=Fledermaus
Blaze=Lohe Blaze=Lohe
@ -49,6 +52,13 @@ Wolf=Wolf
Husk=Wüstenzombie Husk=Wüstenzombie
Zombie=Zombie Zombie=Zombie
Zombie Pigman=Schweinezombie 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 Farmer=Bauer
Fisherman=Fischer Fisherman=Fischer
Fletcher=Pfeilmacher Fletcher=Pfeilmacher
@ -62,3 +72,4 @@ Weapon Smith=Waffenschmied
Tool Smith=Werkzeugschmied Tool Smith=Werkzeugschmied
Cleric=Priester Cleric=Priester
Nitwit=Dorftrottel 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 # 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 Bat=Murciélago
Blaze=Blaze Blaze=Blaze
Chicken=Pollo Chicken=Pollo
Cod=Bacalao
Cow=Vaca Cow=Vaca
Mooshroom=Champivaca Mooshroom=Champiñaca
Creeper=Creeper Creeper=Creeper
Dolphin=Delfín Ender Dragon=Enderdragón
Ender Dragon=Ender Dragon
Enderman=Enderman Enderman=Enderman
Endermite=Endermite Endermite=Endermite
Ghast=Ghast Ghast=Ghast
Elder Guardian=Gran guardián
Guardian=Guardián Guardian=Guardián
Elder Guardian=Guardián Anciano
Donkey=Burro
Horse=Caballo Horse=Caballo
Skeleton Horse=Caballo esquelético
Zombie Horse=Caballo zombie
Donkey=Burro
Mule=Mula Mule=Mula
Skeleton Horse=Caballo esqueleto
Zombie Horse=Caballo zombi
Iron Golem=Golem de hierro Iron Golem=Golem de hierro
Llama=Llama Llama=Llama
Cat=Gato
Ocelot=Ocelote Ocelot=Ocelote
Parrot=Loro Parrot=Loro
Pig=Cerdo Pig=Cerdo
Polar Bear=Oso polar Polar Bear=Oso polar
Killer Bunny=Conejo asesino
Rabbit=Conejo Rabbit=Conejo
Salmon=Salmón Killer Bunny=Conejo asesino
Sheep=Oveja Sheep=Oveja
Shulker=Shulker Shulker=Shulker
Silverfish=Lepisma Silverfish=Lepisma
Skeleton=Esqueleto Skeleton=Esqueleto
Stray=Esqueleto glacial Stray=Esqueleto
Wither Skeleton=Esqueleto del Wither Wither Skeleton=Esqueleto wither
Magma Cube=Cubo de Magma Magma Cube=Cubo de Magma
Slime=Slime Slime=Slime
Snow Golem=Golem de nieve Snow Golem=Golem de nieve
Cave Spider=Araña de las cuevas
Spider=Araña Spider=Araña
Cave Spider=Araña de las cuevas
Squid=Calamar Squid=Calamar
Vex=Ánima Vex=Ánima
Master=Maestro
Villager=Aldeano
Evoker=Invocador Evoker=Invocador
Illusioner=Illusionista Illusioner=Illusionista
Villager=Aldeano
Vindicator=Vindicador Vindicator=Vindicador
Zombie Villager=Aldeano zombi Zombie Villager=Aldeano zombie
Witch=Bruja Witch=Bruja
Wither=Wither Wither=Wither
Wolf=Lobo Wolf=Lobo
Baby Husk=Bebé Zombi Momificado Husk=Husk
Baby Zombie=Bebé Zombi Zombie=Zombie
Husk=Zombi Momificado Zombie Pigman=Cerdo Zombie
Zombie=Zombi Iron Horse Armor=Armadura de hierro para caballo
Baby Zombie Pigman=Bebé Hombrecerdo Zombi 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.
Zombie Pigman=Hombrecerdo Zombi 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 # 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 Agent=Agent
Bat=Chauve-souris Bat=Chauve-souris
Blaze=Blaze Blaze=Blaze
@ -49,6 +52,13 @@ Wolf=Loup
Husk=Zombie Momifié Husk=Zombie Momifié
Zombie=Zombie Zombie=Zombie
Zombie Pigman=Zombie Cochon 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 Farmer=Fermier
Fisherman=Pêcheur Fisherman=Pêcheur
Fletcher=Archer Fletcher=Archer
@ -62,8 +72,4 @@ Weapon Smith=Fabriquant d'arme
Tool Smith=Fabriquant d'outil Tool Smith=Fabriquant d'outil
Cleric=Clerc Cleric=Clerc
Nitwit=Crétin Nitwit=Crétin
Cod=Morue Protects you from death while wielding it=Vous protège de la mort en la maniant
Salmon=Saumon
Dolphin=Dauphin
Pillager=Pilleur
Tropical fish=Poisson tropical

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc # 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=Агент Agent=Агент
Bat=Летучая мышь Bat=Летучая мышь
Blaze=Ифрит Blaze=Ифрит
@ -49,6 +52,13 @@ Wolf=Волк
Husk=Кадавр Husk=Кадавр
Zombie=Зомби Zombie=Зомби
Zombie Pigman=Зомби-свиночеловек 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=Фермер Farmer=Фермер
Fisherman=Рыбак Fisherman=Рыбак
Fletcher=Лучник Fletcher=Лучник
@ -62,3 +72,4 @@ Weapon Smith=Оружейник
Tool Smith=Инструментальщик Tool Smith=Инструментальщик
Cleric=Церковник Cleric=Церковник
Nitwit=Нищий Nitwit=Нищий
Protects you from death while wielding it=Защищает вас от смерти, пока вы владеете им

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc # 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= Agent=
Bat= Bat=
Blaze= Blaze=
@ -49,6 +52,13 @@ Wolf=
Husk= Husk=
Zombie= Zombie=
Zombie Pigman= 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= Farmer=
Fisherman= Fisherman=
Fletcher= Fletcher=
@ -62,8 +72,4 @@ Weapon Smith=
Tool Smith= Tool Smith=
Cleric= Cleric=
Nitwit= Nitwit=
Cod= Protects you from death while wielding it=
Salmon=
Dolphin=
Pillager=
Tropical fish=

View File

@ -1,6 +1,6 @@
name = mobs_mc name = mobs_mc
author = maikerumine author = maikerumine
description = Adds Minecraft-like monsters and animals. description = Adds Minecraft-like monsters and animals.
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core 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 optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items

View File

@ -13,15 +13,16 @@ local pr = PseudoRandom(os.time()*12)
local default_walk_chance = 70 local default_walk_chance = 70
local follow = { -- Returns true if the item is food (taming) for the cat/ocelot
"mcl_fishing:fish_raw", local is_food = function(itemstring)
"mcl_fishing:salmon_raw", for f=1, #mobs_mc.follow.ocelot do
"mcl_fishing:clownfish_raw", if itemstring == mobs_mc.follow.ocelot[f] then
"mcl_fishing:pufferfish_raw", return true
} elseif string.sub(itemstring, 1, 6) == "group:" and minetest.get_item_group(itemstring, string.sub(itemstring, 7, -1)) ~= 0 then
return true
local function is_food(itemstring) end
return table.indexof(follow, itemstring) ~= -1 end
return false
end end
-- Ocelot -- Ocelot
@ -30,8 +31,6 @@ local ocelot = {
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
can_despawn = true, can_despawn = true,
spawn_in_group = 3,
spawn_in_group_min = 1,
hp_min = 10, hp_min = 10,
hp_max = 10, hp_max = 10,
xp_min = 1, xp_min = 1,
@ -66,7 +65,7 @@ local ocelot = {
run_start = 0, run_start = 0,
run_end = 40, run_end = 40,
}, },
follow = follow, follow = mobs_mc.follow.ocelot,
view_range = 12, view_range = 12,
passive = true, passive = true,
attack_type = "dogfight", attack_type = "dogfight",
@ -100,7 +99,7 @@ local ocelot = {
end, end,
} }
mcl_mobs:register_mob("mobs_mc:ocelot", ocelot) mobs:register_mob("mobs_mc:ocelot", ocelot)
-- Cat -- Cat
local cat = table.copy(ocelot) local cat = table.copy(ocelot)
@ -123,9 +122,9 @@ cat.sounds = {
distance = 16, distance = 16,
} }
cat.on_rightclick = function(self, clicker) cat.on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end if mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if self.child then return end if self.child then return end
@ -150,13 +149,13 @@ cat.on_rightclick = function(self, clicker)
end end
mcl_mobs:register_mob("mobs_mc:cat", cat) mobs:register_mob("mobs_mc:cat", cat)
local base_spawn_chance = 5000 local base_spawn_chance = 5000
-- Spawn ocelot -- Spawn ocelot
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i --they get the same as the llama because I'm trying to rework so much of this code right now -j4i
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:ocelot", "mobs_mc:ocelot",
"overworld", "overworld",
"ground", "ground",
@ -171,19 +170,19 @@ minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
5, 5,
mobs_mc.water_level+15, mobs_mc.spawn_height.water+15,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
--[[ --[[
mobs:spawn({ mobs:spawn({
name = "mobs_mc:ocelot", name = "mobs_mc:ocelot",
nodes = { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" }, nodes = mobs_mc.spawn.jungle,
neighbors = {"air"}, neighbors = {"air"},
light_max = minetest.LIGHT_MAX+1, light_max = minetest.LIGHT_MAX+1,
light_min = 0, light_min = 0,
chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate
active_object_count = 12, active_object_count = 12,
min_height = mobs_mc.water_level+1, -- Right above ocean level min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
max_height = mcl_vars.mg_overworld_max, max_height = mobs_mc.spawn_height.overworld_max,
on_spawn = function(self, pos) on_spawn = function(self, pos)
Note: Minecraft has a 1/3 spawn failure rate. Note: Minecraft has a 1/3 spawn failure rate.
In this mod it is emulated by reducing the spawn rate accordingly (see above). In this mod it is emulated by reducing the spawn rate accordingly (see above).
@ -233,4 +232,4 @@ mobs:spawn({
-- spawn eggs -- spawn eggs
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture -- FIXME: The spawn icon shows a cat texture, not an ocelot texture
mcl_mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0) mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0)

View File

@ -8,126 +8,12 @@ local S = minetest.get_translator("mobs_mc")
--################### --###################
--################### PARROT --################### PARROT
--################### --###################
local shoulders = {
left = vector.new(-3.75,10.5,0),
right = vector.new(3.75,10.5,0)
}
local function table_get_rand(tbl)
local keys = {}
for k in pairs(tbl) do
table.insert(keys, k)
end
return tbl[keys[math.random(#keys)]]
end
local function get_random_mob_sound()
local t = table.copy(minetest.registered_entities)
table.shuffle(t)
for _,e in pairs(t) do
if e.is_mob and e.sounds and #e.sounds > 0 then
return table_get_rand(e.sounds)
end
end
return minetest.registered_entities["mobs_mc:parrot"].sounds.random
end
local function imitate_mob_sound(self,mob) mobs:register_mob("mobs_mc:parrot", {
local snd = mob.sounds.random
if not snd or mob.name == "mobs_mc:parrot" or math.random(20) == 1 then
snd = get_random_mob_sound()
end
return minetest.sound_play(snd, {
pos = self.object:get_pos(),
gain = 1.0,
pitch = 2.5,
max_hear_distance = self.sounds and self.sounds.distance or 32
}, true)
end
local function check_mobimitate(self,dtime)
if not self._mobimitate_timer or self._mobimitate_timer > 30 then
self._mobimitate_timer = 0
for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),20)) do
local l = o:get_luaentity()
if l and l.is_mob and l.name ~= "mobs_mc:parrot" then
imitate_mob_sound(self,l)
return
end
end
end
self._mobimitate_timer = self._mobimitate_timer + dtime
end
--find a free shoulder or return nil
local function get_shoulder(player)
local sh = "left"
for _,o in pairs(player:get_children()) do
local l = o:get_luaentity()
if l and l.name == "mobs_mc:parrot" then
local _,_,a = l.object:get_attach()
for _,s in pairs(shoulders) do
if a and vector.equals(a,s) then
if sh == "left" then
sh = "right"
else
return
end
end
end
end
end
return shoulders[sh]
end
local function perch(self,player)
if self.tamed and player:get_player_name() == self.owner and not self.object:get_attach() then
local shoulder = get_shoulder(player)
if not shoulder then return true end
self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true)
mcl_mobs:set_animation(self, "stand")
end
end
local function check_perch(self,dtime)
if self.object:get_attach() then
for _,p in pairs(minetest.get_connected_players()) do
for _,o in pairs(p:get_children()) do
local l = o:get_luaentity()
if l and l.name == "mobs_mc:parrot" then
local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name
local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name
local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name
if ( n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0) and
not minetest.is_creative_enabled(p:get_player_name()) then
o:set_detach()
self.detach_timer = 0
return
end
end
end
end
elseif not self.detach_timer then
for _,p in pairs(minetest.get_connected_players()) do
if vector.distance(self.object:get_pos(),p:get_pos()) < 0.5 then
perch(self,p)
return
end
end
elseif self.detach_timer then
if self.detach_timer > 1 then
self.detach_timer = nil
else
self.detach_timer = self.detach_timer + dtime
end
end
end
mcl_mobs:register_mob("mobs_mc:parrot", {
description = S("Parrot"), description = S("Parrot"),
type = "passive", type = "npc",
spawn_class = "passive", spawn_class = "passive",
pathfinding = 1, pathfinding = 1,
hp_min = 6, hp_min = 6,
@ -149,7 +35,7 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
distance = 16, distance = 16,
}, },
drops = { drops = {
{name = "mcl_mobitems:feather", {name = mobs_mc.items.feather,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2, max = 2,
@ -159,12 +45,12 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
stand_speed = 50, stand_speed = 50,
walk_speed = 50, walk_speed = 50,
fly_speed = 50, fly_speed = 50,
stand_start = 0, stand_start = 30,
stand_end = 0, stand_end = 45,
fly_start = 30, fly_start = 30,
fly_end = 45, fly_end = 45,
walk_start = 0, walk_start = 30,
walk_end = 20, walk_end = 45,
-- TODO: actual walk animation -- TODO: actual walk animation
--walk_start = 0, --walk_start = 0,
--walk_end = 20, --walk_end = 20,
@ -180,17 +66,12 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
makes_footstep_sound = false, makes_footstep_sound = false,
fear_height = 0, fear_height = 0,
view_range = 16, view_range = 16,
follow = { follow = mobs_mc.follow.parrot,
"mcl_farming:wheat_seeds",
"mcl_farming:melon_seeds",
"mcl_farming:pumpkin_seeds",
"mcl_farming:beetroot_seeds",
},
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if self._doomed then return end if self._doomed then return end
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
-- Kill parrot if fed with cookie -- Kill parrot if fed with cookie
if item:get_name() == "mcl_farming:cookie" then if item:get_name() == mobs_mc.items.cookie then
minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true) minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true)
self.health = 0 self.health = 0
-- Doomed to die -- Doomed to die
@ -201,23 +82,17 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
end end
return return
end end
-- Feed to tame, but not breed -- Feed to tame, but not breed
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
perch(self,clicker) if mobs:protect(self, clicker) then return end
end, if mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end
do_custom = function(self,dtime)
check_perch(self,dtime)
check_mobimitate(self,dtime)
end,
do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later....
if self.object:get_attach() == puncher then
return false --return false explicitly here. mcl_mobs checks for that
end
end, end,
}) })
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:parrot", "mobs_mc:parrot",
"overworld", "overworld",
"ground", "ground",
@ -232,8 +107,8 @@ minetest.LIGHT_MAX+1,
7, 7,
30000, 30000,
1, 1,
mobs_mc.water_level+7, mobs_mc.spawn_height.water+7,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)

View File

@ -2,7 +2,7 @@
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:pig", { mobs:register_mob("mobs_mc:pig", {
description = S("Pig"), description = S("Pig"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
@ -25,7 +25,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
run_velocity = 3, run_velocity = 3,
follow_velocity = 3.4, follow_velocity = 3.4,
drops = { drops = {
{name = "mcl_mobitems:porkchop", {name = mobs_mc.items.porkchop_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 3, max = 3,
@ -50,12 +50,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
run_start = 0, run_start = 0,
run_end = 40, run_end = 40,
}, },
follow = { follow = mobs_mc.follow.pig,
"mcl_farming:potato_item",
"mcl_farming:carrot_item",
"mcl_farming:beetroot_item",
"mcl_mobitems:carrot_on_a_stick"
},
view_range = 8, view_range = 8,
do_custom = function(self, dtime) do_custom = function(self, dtime)
@ -74,7 +69,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
-- if driver present allow control of horse -- if driver present allow control of horse
if self.driver then 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 return false -- skip rest of mob functions
end end
@ -87,7 +82,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
-- drop saddle when horse is killed while riding -- drop saddle when horse is killed while riding
-- also detach from horse properly -- also detach from horse properly
if self.driver then 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
end, end,
@ -98,10 +93,10 @@ mcl_mobs:register_mob("mobs_mc:pig", {
local wielditem = clicker:get_wielded_item() local wielditem = clicker:get_wielded_item()
-- Feed pig -- Feed pig
if wielditem:get_name() ~= "mcl_mobitems:carrot_on_a_stick" then if wielditem:get_name() ~= mobs_mc.items.carrot_on_a_stick then
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
end end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if self.child then if self.child then
return return
@ -109,7 +104,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
-- Put saddle on pig -- Put saddle on pig
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then
self.base_texture = { self.base_texture = {
"blank.png", -- baby "blank.png", -- baby
"mobs_mc_pig.png", -- base "mobs_mc_pig.png", -- base
@ -121,11 +116,11 @@ mcl_mobs:register_mob("mobs_mc:pig", {
self.saddle = "yes" self.saddle = "yes"
self.tamed = true self.tamed = true
self.drops = { self.drops = {
{name = "mcl_mobitems:porkchop", {name = mobs_mc.items.porkchop_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 3,}, max = 3,},
{name = "mcl_mobitems:saddle", {name = mobs_mc.items.saddle,
chance = 1, chance = 1,
min = 1, min = 1,
max = 1,}, max = 1,},
@ -144,13 +139,13 @@ mcl_mobs:register_mob("mobs_mc:pig", {
local name = clicker:get_player_name() local name = clicker:get_player_name()
if self.driver and clicker == self.driver then if self.driver and clicker == self.driver then
-- Detach if already attached -- Detach if already attached
mcl_mobs.detach(clicker, {x=1, y=0, z=0}) mobs.detach(clicker, {x=1, y=0, z=0})
return return
elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == "mcl_mobitems:carrot_on_a_stick" then elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == mobs_mc.items.carrot_on_a_stick then
-- Ride pig if it has a saddle and player uses a carrot on a stick -- Ride pig if it has a saddle and player uses a carrot on a stick
mcl_mobs.attach(self, clicker) mobs.attach(self, clicker)
if not minetest.is_creative_enabled(clicker:get_player_name()) then if not minetest.is_creative_enabled(clicker:get_player_name()) then
@ -162,7 +157,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
if def.sounds and def.sounds.breaks then if def.sounds and def.sounds.breaks then
minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true) minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true)
end end
wielditem = {name = "mcl_fishing:fishing_rod", count = 1} wielditem = {name = mobs_mc.items.fishing_rod, count = 1}
else else
wielditem:add_wear(2521) wielditem:add_wear(2521)
end end
@ -172,13 +167,13 @@ mcl_mobs:register_mob("mobs_mc:pig", {
-- Capture pig -- Capture pig
elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" 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, end,
on_breed = function(parent1, parent2) on_breed = function(parent1, parent2)
local pos = parent1.object:get_pos() 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 if child then
local ent_c = child:get_luaentity() local ent_c = child:get_luaentity()
ent_c.tamed = true ent_c.tamed = true
@ -188,18 +183,23 @@ mcl_mobs:register_mob("mobs_mc:pig", {
end, end,
}) })
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:pig", "mobs_mc:pig",
"overworld", "overworld",
"ground", "ground",
{ {
"flat", "flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga", "MegaTaiga",
"MegaSpruceTaiga", "MegaSpruceTaiga",
"ExtremeHills", "ExtremeHills",
"ExtremeHills_beach", "ExtremeHills_beach",
"ExtremeHillsM", "ExtremeHillsM",
"ExtremeHills+", "ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach", "StoneBeach",
"Plains", "Plains",
"Plains_beach", "Plains_beach",
@ -230,8 +230,8 @@ minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
8, 8,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)

View File

@ -1,122 +0,0 @@
local S = minetest.get_translator("mobs_mc")
local function reload(self)
if not self.object:get_pos() then return end
minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true)
local props = self.object:get_properties()
if not props then return end
props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16"
self.object:set_properties(props)
end
local function reset_animation(self, animation)
if not self.object:get_pos() or self._current_animation ~= animation then return end
self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this
mcl_mobs:set_animation(self, animation)
end
pillager = {
description = S("Pillager"),
type = "monster",
spawn_class = "hostile",
hp_min = 24,
hp_max = 24,
xp_min = 6,
xp_max = 6,
breath_max = -1,
eye_height = 1.5,
shoot_interval = 3,
shoot_offset = 1.5,
armor = {fleshy = 100},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},
pathfinding = 1,
group_attack = true,
visual = "mesh",
mesh = "mobs_mc_pillager.b3d",
visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true,
walk_velocity = 1.2,
run_velocity = 4,
view_range = 16,
fear_height = 4,
arrow = "mcl_bows:arrow_entity",
attack_type = "dogshoot", -- Alternate punching/shooting
reach = 0, -- Punching max distance
damage = 0, -- Punching damage
dogshoot_switch = 1, -- Start of shooting
dogshoot_count_max = 5, -- Max time spent shooting (standing)
dogshoot_count2_max = 1, -- Max time spent punching (running)
sounds = {
random = "mobs_mc_pillager_grunt2",
war_cry = "mobs_mc_pillager_grunt1",
death = "mobs_mc_pillager_ow2",
damage = "mobs_mc_pillager_ow1",
distance = 16,
},
textures = {
{
"mobs_mc_pillager.png", -- Skin
"mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item
}
},
drops = {
{
name = "mcl_bows:arrow",
chance = 1,
min = 0,
max = 2,
looting = "common",
},
{
name = "mcl_bows:crossbow",
chance = 100 / 8.5,
min = 1,
max = 1,
looting = "rare",
},
},
animation = {
unloaded_walk_start = 1, unloaded_walk_end = 40,
unloaded_stand_start = 41, unloaded_stand_end = 60,
reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20,
stand_start = 101, stand_end = 109, stand_speed = 6,
walk_start = 111, walk_end = 150, walk_speed = 30,
run_start = 111, run_end = 150, run_speed = 50,
reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20,
die_start = 191, die_end = 192, die_speed = 15,
stand_unloaded_start = 40, stand_unloaded_end = 59,
die_loop = false,
},
shoot_arrow = function(self, pos, dir)
minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true)
local props = self.object:get_properties()
props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16"
self.object:set_properties(props)
local old_anim = self._current_animation
if old_anim == "run" or old_anim == "walk" then
mcl_mobs:set_animation(self, "reload_run")
end
if old_anim == "stand" then
mcl_mobs:set_animation(self, "reload_stand")
end
self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise
minetest.after(1, reload, self)
minetest.after(2, reset_animation, self, old_anim)
-- 2-4 damage per arrow
local dmg = math.max(4, math.random(2, 8))
mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
-- While we are at it, change the sounds since there is no way to do this in Mobs Redo
if self.sounds and self.sounds.random then
self.sounds = table.copy(self.sounds)
self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2)
end
-- Randomize reload time
self.shoot_interval = math.random(3, 4)
end,
}
mcl_mobs:register_mob("mobs_mc:pillager", pillager)
mcl_mobs:register_egg("mobs_mc:pillager", S("Pillager"), "mobs_mc_spawn_icon_pillager.png", 0)

View File

@ -7,7 +7,7 @@ local S = minetest.get_translator("mobs_mc")
--################### --###################
mcl_mobs:register_mob("mobs_mc:polar_bear", { mobs:register_mob("mobs_mc:polar_bear", {
description = S("Polar Bear"), description = S("Polar Bear"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
@ -34,13 +34,13 @@ mcl_mobs:register_mob("mobs_mc:polar_bear", {
attack_type = "dogfight", attack_type = "dogfight",
drops = { drops = {
-- 3/4 chance to drop raw fish (poor approximation) -- 3/4 chance to drop raw fish (poor approximation)
{name = "mcl_fishing:fish_raw", {name = mobs_mc.items.fish_raw,
chance = 2, chance = 2,
min = 0, min = 0,
max = 2, max = 2,
looting = "common",}, looting = "common",},
-- 1/4 to drop raw salmon -- 1/4 to drop raw salmon
{name = "mcl_fishing:salmon_raw", {name = mobs_mc.items.salmon_raw,
chance = 4, chance = 4,
min = 0, min = 0,
max = 2, max = 2,
@ -68,7 +68,7 @@ mcl_mobs:register_mob("mobs_mc:polar_bear", {
}) })
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:polar_bear", "mobs_mc:polar_bear",
"overworld", "overworld",
"ground", "ground",
@ -76,14 +76,15 @@ mcl_mobs:spawn_specific(
"ColdTaiga", "ColdTaiga",
"IcePlainsSpikes", "IcePlainsSpikes",
"IcePlains", "IcePlains",
"ExtremeHills+_snowtop",
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
7000, 7000,
3, 3,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn egg -- spawn egg
mcl_mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)

View File

@ -6,10 +6,9 @@ local rabbit = {
description = S("Rabbit"), description = S("Rabbit"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 3,
passive = true, passive = true,
reach = 1, reach = 1,
hp_min = 3, hp_min = 3,
hp_max = 3, hp_max = 3,
xp_min = 1, xp_min = 1,
@ -43,9 +42,9 @@ local rabbit = {
runaway = true, runaway = true,
jump = true, jump = true,
drops = { drops = {
{name = "mcl_mobitems:rabbit", chance = 1, min = 0, max = 1, looting = "common",}, {name = mobs_mc.items.rabbit_raw, chance = 1, min = 0, max = 1, looting = "common",},
{name = "mcl_mobitems:rabbit_hide", chance = 1, min = 0, max = 1, looting = "common",}, {name = mobs_mc.items.rabbit_hide, chance = 1, min = 0, max = 1, looting = "common",},
{name = "mcl_mobitems:rabbit_foot", chance = 10, min = 0, max = 1, looting = "rare", looting_factor = 0.03,}, {name = mobs_mc.items.rabbit_foot, chance = 10, min = 0, max = 1, looting = "rare", looting_factor = 0.03,},
}, },
fear_height = 4, fear_height = 4,
animation = { animation = {
@ -55,29 +54,16 @@ local rabbit = {
run_start = 0, run_end = 20, run_start = 0, run_end = 20,
}, },
-- Follow (yellow) dangelions, carrots and golden carrots -- Follow (yellow) dangelions, carrots and golden carrots
follow = { follow = mobs_mc.follow.rabbit,
"mcl_flowers:dandelion",
"mcl_farming:carrot_item",
"mcl_farming:carrot_item_gold",
},
view_range = 8, view_range = 8,
-- Eat carrots and reduce their growth stage by 1 -- Eat carrots and reduce their growth stage by 1
replace_rate = 10, replace_rate = 10,
replace_what = { replace_what = mobs_mc.replace.rabbit,
{"mcl_farming:carrot", "mcl_farming:carrot_7", 0},
{"mcl_farming:carrot_7", "mcl_farming:carrot_6", 0},
{"mcl_farming:carrot_6", "mcl_farming:carrot_5", 0},
{"mcl_farming:carrot_5", "mcl_farming:carrot_4", 0},
{"mcl_farming:carrot_4", "mcl_farming:carrot_3", 0},
{"mcl_farming:carrot_3", "mcl_farming:carrot_2", 0},
{"mcl_farming:carrot_2", "mcl_farming:carrot_1", 0},
{"mcl_farming:carrot_1", "air", 0},
},
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
-- Feed, tame protect or capture -- Feed, tame protect or capture
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end if mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end
end, end,
do_custom = function(self) do_custom = function(self)
-- Easter egg: Change texture if rabbit is named “Toast” -- Easter egg: Change texture if rabbit is named “Toast”
@ -94,7 +80,7 @@ local rabbit = {
end, end,
} }
mcl_mobs:register_mob("mobs_mc:rabbit", rabbit) mobs:register_mob("mobs_mc:rabbit", rabbit)
-- The killer bunny (Only with spawn egg) -- The killer bunny (Only with spawn egg)
local killer_bunny = table.copy(rabbit) local killer_bunny = table.copy(rabbit)
@ -120,30 +106,40 @@ killer_bunny.do_custom = function(self)
end end
end end
mcl_mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) mobs:register_mob("mobs_mc:killer_bunny", killer_bunny)
-- Mob spawning rules. -- Mob spawning rules.
-- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out -- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:rabbit", "mobs_mc:rabbit",
"overworld", "overworld",
"ground", "ground",
{ {
"Desert",
"FlowerForest", "FlowerForest",
"Swampland",
"Taiga", "Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga", "MegaSpruceTaiga",
"MegaTaiga", "MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga", "ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
}, },
9, 9,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
8, 8,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
--[[ --[[
local spawn = { local spawn = {
@ -153,21 +149,21 @@ local spawn = {
active_object_count = 10, active_object_count = 10,
min_light = 0, min_light = 0,
max_light = minetest.LIGHT_MAX+1, max_light = minetest.LIGHT_MAX+1,
min_height = mcl_vars.mg_overworld_min, min_height = mobs_mc.spawn_height.overworld_min,
max_height = mcl_vars.mg_overworld_max, max_height = mobs_mc.spawn_height.overworld_max,
} }
local spawn_desert = table.copy(spawn) local spawn_desert = table.copy(spawn)
spawn_desert.nodes = { "mcl_core:sand", "mcl_core:sandstone" } spawn_desert.nodes = mobs_mc.spawn.desert
spawn_desert.on_spawn = function(self, pos) spawn_desert.on_spawn = function(self, pos)
local texture = "mobs_mc_rabbit_gold.png" local texture = "mobs_mc_rabbit_gold.png"
self.base_texture = { "mobs_mc_rabbit_gold.png" } self.base_texture = { "mobs_mc_rabbit_gold.png" }
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
end end
mcl_mobs:spawn(spawn_desert) mobs:spawn(spawn_desert)
local spawn_snow = table.copy(spawn) local spawn_snow = table.copy(spawn)
spawn_snow.nodes = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" } spawn_snow.nodes = mobs_mc.spawn.snow
spawn_snow.on_spawn = function(self, pos) spawn_snow.on_spawn = function(self, pos)
local texture local texture
local r = math.random(1, 100) local r = math.random(1, 100)
@ -181,10 +177,10 @@ spawn_snow.on_spawn = function(self, pos)
self.base_texture = { texture } self.base_texture = { texture }
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
end end
mcl_mobs:spawn(spawn_snow) mobs:spawn(spawn_snow)
local spawn_grass = table.copy(spawn) local spawn_grass = table.copy(spawn)
spawn_grass.nodes = { "mcl_core:dirt_with_grass" } spawn_grass.nodes = mobs_mc.spawn.grassland
spawn_grass.on_spawn = function(self, pos) spawn_grass.on_spawn = function(self, pos)
local texture local texture
local r = math.random(1, 100) local r = math.random(1, 100)
@ -201,11 +197,11 @@ spawn_grass.on_spawn = function(self, pos)
self.base_texture = { texture } self.base_texture = { texture }
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
end end
mcl_mobs:spawn(spawn_grass) mobs:spawn(spawn_grass)
]]-- ]]--
-- Spawn egg -- Spawn egg
mcl_mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)
-- Note: This spawn egg does not exist in Minecraft -- Note: This spawn egg does not exist in Minecraft
mcl_mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image

View File

@ -1,228 +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(minetest.get_current_modname())
--###################
--################### salmon
--###################
local salmon = {
type = "animal",
spawn_class = "water",
can_despawn = true,
passive = true,
hp_min = 3,
hp_max = 3,
xp_min = 1,
xp_max = 3,
armor = 100,
spawn_in_group = 5,
tilt_swim = true,
collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.79, 0.4},
visual = "mesh",
mesh = "extra_mobs_salmon.b3d",
textures = {
{"extra_mobs_salmon.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:salmon_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,
swim = true,
fly = true,
fly_in = "mcl_core:water_source",
breathes_in_water = true,
jump = false,
view_range = 16,
runaway = true,
fear_height = 4,
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_salmon")
awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing")
end
end
}
mcl_mobs:register_mob("mobs_mc:salmon", salmon)
--spawning TODO: in schools
local water = 0
mcl_mobs:spawn_specific(
"mobs_mc:salmon",
"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:salmon", S("Salmon"), "extra_mobs_spawn_icon_salmon.png", 0)

View File

@ -8,22 +8,21 @@ local S = minetest.get_translator("mobs_mc")
local colors = { local colors = {
-- group = { wool, textures } -- group = { wool, textures }
unicolor_white = { "mcl_wool:white", "#FFFFFF00" }, unicolor_white = { mobs_mc.items.wool_white, "#FFFFFF00" },
unicolor_dark_orange = { "mcl_wool:brown", "#502A00D0" }, unicolor_dark_orange = { mobs_mc.items.wool_brown, "#502A00D0" },
unicolor_grey = { "mcl_wool:silver", "#5B5B5BD0" }, unicolor_grey = { mobs_mc.items.wool_light_grey, "#5B5B5BD0" },
unicolor_darkgrey = { "mcl_wool:grey", "#303030D0" }, unicolor_darkgrey = { mobs_mc.items.wool_grey, "#303030D0" },
unicolor_blue = { "mcl_wool:blue", "#0000CCD0" }, unicolor_blue = { mobs_mc.items.wool_blue, "#0000CCD0" },
unicolor_dark_green = { "mcl_wool:green", "#005000D0" }, unicolor_dark_green = { mobs_mc.items.wool_green, "#005000D0" },
unicolor_green = { "mcl_wool:lime", "#50CC00D0" }, unicolor_green = { mobs_mc.items.wool_lime, "#50CC00D0" },
unicolor_violet = { "mcl_wool:purple" , "#5000CCD0" }, unicolor_violet = { mobs_mc.items.wool_purple , "#5000CCD0" },
unicolor_light_red = { "mcl_wool:pink", "#FF5050D0" }, unicolor_light_red = { mobs_mc.items.wool_pink, "#FF5050D0" },
unicolor_yellow = { "mcl_wool:yellow", "#CCCC00D0" }, unicolor_yellow = { mobs_mc.items.wool_yellow, "#CCCC00D0" },
unicolor_orange = { "mcl_wool:orange", "#CC5000D0" }, unicolor_orange = { mobs_mc.items.wool_orange, "#CC5000D0" },
unicolor_red = { "mcl_wool:red", "#CC0000D0" }, unicolor_red = { mobs_mc.items.wool_red, "#CC0000D0" },
unicolor_cyan = { "mcl_wool:cyan", "#00CCCCD0" }, unicolor_cyan = { mobs_mc.items.wool_cyan, "#00CCCCD0" },
unicolor_red_violet = { "mcl_wool:magenta", "#CC0050D0" }, unicolor_red_violet = { mobs_mc.items.wool_magenta, "#CC0050D0" },
unicolor_black = { "mcl_wool:black", "#000000D0" }, unicolor_black = { mobs_mc.items.wool_black, "#000000D0" },
unicolor_light_blue = { "mcl_wool:light_blue", "#5050FFD0" },
} }
local rainbow_colors = { local rainbow_colors = {
@ -39,6 +38,10 @@ local rainbow_colors = {
"unicolor_red_violet" "unicolor_red_violet"
} }
if minetest.get_modpath("mcl_wool") ~= nil then
colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" }
end
local sheep_texture = function(color_group) local sheep_texture = function(color_group)
if not color_group then if not color_group then
color_group = "unicolor_white" color_group = "unicolor_white"
@ -52,7 +55,7 @@ end
local gotten_texture = { "blank.png", "mobs_mc_sheep.png" } local gotten_texture = { "blank.png", "mobs_mc_sheep.png" }
--mcsheep --mcsheep
mcl_mobs:register_mob("mobs_mc:sheep", { mobs:register_mob("mobs_mc:sheep", {
description = S("Sheep"), description = S("Sheep"),
type = "animal", type = "animal",
spawn_class = "passive", spawn_class = "passive",
@ -70,10 +73,8 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
color = "unicolor_white", color = "unicolor_white",
makes_footstep_sound = true, makes_footstep_sound = true,
walk_velocity = 1, walk_velocity = 1,
runaway = true,
runaway_from = {"mobs_mc:wolf"},
drops = { drops = {
{name = "mcl_mobitems:mutton", {name = mobs_mc.items.mutton_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2, max = 2,
@ -98,15 +99,12 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
walk_start = 0, walk_end = 40, walk_start = 0, walk_end = 40,
run_start = 0, run_end = 40, run_start = 0, run_end = 40,
}, },
follow = { "mcl_farming:wheat_item" }, follow = mobs_mc.follow.sheep,
view_range = 12, view_range = 12,
-- Eat grass -- Eat grass
replace_rate = 20, replace_rate = 20,
replace_what = { replace_what = mobs_mc.replace.sheep,
{ "mcl_core:dirt_with_grass", "mcl_core:dirt", -1 },
{ "mcl_flowers:tallgrass", "air", 0 },
},
-- Properly regrow wool after eating grass -- Properly regrow wool after eating grass
on_replace = function(self, pos, oldnode, newnode) on_replace = function(self, pos, oldnode, newnode)
if not self.color or not colors[self.color] then if not self.color or not colors[self.color] then
@ -116,7 +114,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
self.base_texture = sheep_texture(self.color) self.base_texture = sheep_texture(self.color)
self.object:set_properties({ textures = self.base_texture }) self.object:set_properties({ textures = self.base_texture })
self.drops = { self.drops = {
{name = "mcl_mobitems:mutton", {name = mobs_mc.items.mutton_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2,}, max = 2,},
@ -154,7 +152,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
self.base_texture = sheep_texture(self.color) self.base_texture = sheep_texture(self.color)
self.object:set_properties({ textures = self.base_texture }) self.object:set_properties({ textures = self.base_texture })
self.drops = { self.drops = {
{name = "mcl_mobitems:mutton", {name = mobs_mc.items.mutton_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2,}, max = 2,},
@ -197,10 +195,10 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end if mobs:protect(self, clicker) then return end
if item:get_name() == "mcl_tools:shears" and not self.gotten and not self.child then if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then
self.gotten = true self.gotten = true
local pos = self.object:get_pos() local pos = self.object:get_pos()
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
@ -214,11 +212,11 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
textures = self.base_texture, textures = self.base_texture,
}) })
if not minetest.is_creative_enabled(clicker:get_player_name()) then 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) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
end end
self.drops = { self.drops = {
{name = "mcl_mobitems:mutton", {name = mobs_mc.items.mutton_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2,}, max = 2,},
@ -240,7 +238,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
}) })
self.color = group self.color = group
self.drops = { self.drops = {
{name = "mcl_mobitems:mutton", {name = mobs_mc.items.mutton_raw,
chance = 1, chance = 1,
min = 1, min = 1,
max = 2,}, max = 2,},
@ -254,12 +252,12 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
end end
return return
end end
if mcl_mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end if mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end
end, end,
on_breed = function(parent1, parent2) on_breed = function(parent1, parent2)
-- Breed sheep and choose a fur color for the child. -- Breed sheep and choose a fur color for the child.
local pos = parent1.object:get_pos() 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 if child then
local ent_c = child:get_luaentity() local ent_c = child:get_luaentity()
local color1 = parent1.color local color1 = parent1.color
@ -306,7 +304,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
end end
end, end,
}) })
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:sheep", "mobs_mc:sheep",
"overworld", "overworld",
"ground", "ground",
@ -348,13 +346,13 @@ mcl_mobs:spawn_specific(
"Swampland", "Swampland",
"Swampland_shore" "Swampland_shore"
}, },
9, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
30, 30,
15000, 15000,
3, 3,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)

View File

@ -11,7 +11,7 @@ local S = minetest.get_translator("mobs_mc")
-- animation 45-80 is transition between passive and attack stance -- animation 45-80 is transition between passive and attack stance
mcl_mobs:register_mob("mobs_mc:shulker", { mobs:register_mob("mobs_mc:shulker", {
description = S("Shulker"), description = S("Shulker"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -33,10 +33,9 @@ mcl_mobs:register_mob("mobs_mc:shulker", {
-- TODO: Make shulker dye-able -- TODO: Make shulker dye-able
visual_size = {x=3, y=3}, visual_size = {x=3, y=3},
walk_chance = 0, walk_chance = 0,
knock_back = false,
jump = false, jump = false,
drops = { drops = {
{name = "mcl_mobitems:shulker_shell", {name = mobs_mc.items.shulker_shell,
chance = 2, chance = 2,
min = 1, min = 1,
max = 1, max = 1,
@ -56,7 +55,7 @@ mcl_mobs:register_mob("mobs_mc:shulker", {
}) })
-- bullet arrow (weapon) -- bullet arrow (weapon)
mcl_mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_arrow("mobs_mc:shulkerbullet", {
visual = "sprite", visual = "sprite",
visual_size = {x = 0.25, y = 0.25}, visual_size = {x = 0.25, y = 0.25},
textures = {"mobs_mc_shulkerbullet.png"}, textures = {"mobs_mc_shulkerbullet.png"},
@ -81,9 +80,9 @@ mcl_mobs:register_arrow("mobs_mc:shulkerbullet", {
}) })
mcl_mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:shulker", "mobs_mc:shulker",
"end", "end",
"ground", "ground",
@ -95,5 +94,5 @@ minetest.LIGHT_MAX+1,
30, 30,
5000, 5000,
2, 2,
mcl_vars.mg_end_min, mobs_mc.spawn_height.end_min,
mcl_vars.mg_end_max) mobs_mc.spawn_height.end_max)

View File

@ -4,7 +4,7 @@
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:silverfish", { mobs:register_mob("mobs_mc:silverfish", {
description = S("Silverfish"), description = S("Silverfish"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -35,14 +35,7 @@ mcl_mobs:register_mob("mobs_mc:silverfish", {
run_velocity = 2, run_velocity = 2,
jump = true, jump = true,
fear_height = 4, fear_height = 4,
replace_what = { replace_what = mobs_mc.replace.silverfish,
{"mcl_core:stone", "mcl_monster_eggs:monster_egg_stone", -1},
{"mcl_core:cobble", "mcl_monster_eggs:monster_egg_cobble", -1},
{"mcl_core:stonebrick", "mcl_monster_eggs:monster_egg_stonebrick", -1},
{"mcl_core:stonebrickmossy", "mcl_monster_eggs:monster_egg_stonebrickmossy", -1},
{"mcl_core:stonebrickcracked", "mcl_monster_eggs:monster_egg_stonebrickcracked", -1},
{"mcl_core:stonebrickcarved", "mcl_monster_eggs:monster_egg_stonebrickcarved", -1},
},
replace_rate = 2, replace_rate = 2,
animation = { animation = {
speed_normal = 25, speed_run = 50, speed_normal = 25, speed_run = 50,
@ -56,7 +49,7 @@ mcl_mobs:register_mob("mobs_mc:silverfish", {
reach = 1, reach = 1,
}) })
mcl_mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0)
-- Monster egg blocks (Minetest Game) -- Monster egg blocks (Minetest Game)
if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then

View File

@ -45,17 +45,17 @@ local skeleton = {
damage = 2, damage = 2,
reach = 2, reach = 2,
drops = { drops = {
{name = "mcl_bows:arrow", {name = mobs_mc.items.arrow,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
looting = "common",}, looting = "common",},
{name = "mcl_bows:bow", {name = mobs_mc.items.bow,
chance = 100 / 8.5, chance = 100 / 8.5,
min = 1, min = 1,
max = 1, max = 1,
looting = "rare",}, looting = "rare",},
{name = "mcl_mobitems:bone", {name = mobs_mc.items.bone,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
@ -63,7 +63,7 @@ local skeleton = {
-- Head -- Head
-- TODO: Only drop if killed by charged creeper -- TODO: Only drop if killed by charged creeper
{name = "mcl_heads:skeleton", {name = mobs_mc.items.head_skeleton,
chance = 200, -- 0.5% chance chance = 200, -- 0.5% chance
min = 1, min = 1,
max = 1,}, max = 1,},
@ -102,7 +102,7 @@ local skeleton = {
harmed_by_heal = true, harmed_by_heal = true,
} }
mcl_mobs:register_mob("mobs_mc:skeleton", skeleton) mobs:register_mob("mobs_mc:skeleton", skeleton)
--################### --###################
@ -139,10 +139,10 @@ table.insert(stray.drops, {
end, end,
}) })
mcl_mobs:register_mob("mobs_mc:stray", stray) mobs:register_mob("mobs_mc:stray", stray)
-- Overworld spawn -- Overworld spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:skeleton", "mobs_mc:skeleton",
"overworld", "overworld",
"ground", "ground",
@ -162,6 +162,7 @@ mcl_mobs:spawn_specific(
"Plains", "Plains",
"Desert", "Desert",
"ColdTaiga", "ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes", "IcePlainsSpikes",
"SunflowerPlains", "SunflowerPlains",
"IcePlains", "IcePlains",
@ -188,6 +189,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach", "ExtremeHills_beach",
"ColdTaiga_beach", "ColdTaiga_beach",
"Swampland_shore", "Swampland_shore",
"MushroomIslandShore",
"JungleM_shore", "JungleM_shore",
"Jungle_shore", "Jungle_shore",
"MesaPlateauFM_sandlevel", "MesaPlateauFM_sandlevel",
@ -226,6 +228,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean", "Forest_deep_ocean",
"JungleM_deep_ocean", "JungleM_deep_ocean",
"FlowerForest_deep_ocean", "FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean", "MegaTaiga_ocean",
"StoneBeach_deep_ocean", "StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean", "IcePlainsSpikes_deep_ocean",
@ -235,6 +238,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean", "MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean", "ExtremeHills+_deep_ocean",
"ExtremeHills_ocean", "ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean", "Forest_ocean",
"MegaTaiga_deep_ocean", "MegaTaiga_deep_ocean",
"JungleEdge_ocean", "JungleEdge_ocean",
@ -260,6 +264,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground", "RoofedForest_underground",
"Jungle_underground", "Jungle_underground",
"Swampland_underground", "Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground", "BirchForest_underground",
"Plains_underground", "Plains_underground",
"MesaPlateauF_underground", "MesaPlateauF_underground",
@ -287,29 +292,29 @@ mcl_mobs:spawn_specific(
20, 20,
17000, 17000,
2, 2,
mcl_vars.mg_overworld_min, mobs_mc.spawn_height.overworld_min,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- Nether spawn -- Nether spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:skeleton", "mobs_mc:skeleton",
"nether", "nether",
"ground", "ground",
{ {
"SoulsandValley", "Nether"
}, },
0, 0,
minetest.LIGHT_MAX+1, 7,
30, 30,
10000, 10000,
3, 3,
mcl_vars.mg_nether_min, mobs_mc.spawn_height.nether_min,
mcl_vars.mg_nether_max) mobs_mc.spawn_height.nether_max)
-- Stray spawn -- Stray spawn
-- TODO: Spawn directly under the sky -- TODO: Spawn directly under the sky
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:stray", "mobs_mc:stray",
"overworld", "overworld",
"ground", "ground",
@ -324,10 +329,10 @@ mcl_mobs:spawn_specific(
20, 20,
19000, 19000,
2, 2,
mobs_mc.water_level, mobs_mc.spawn_height.water,
mcl_vars.mg_overworld_max) mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0) mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0)
mcl_mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0) mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0)

View File

@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc")
--################### WITHER SKELETON --################### WITHER SKELETON
--################### --###################
mcl_mobs:register_mob("mobs_mc:witherskeleton", { mobs:register_mob("mobs_mc:witherskeleton", {
description = S("Wither Skeleton"), description = S("Wither Skeleton"),
type = "monster", type = "monster",
spawn_class = "hostile", spawn_class = "hostile",
@ -44,19 +44,19 @@ mcl_mobs:register_mob("mobs_mc:witherskeleton", {
damage = 7, damage = 7,
reach = 2, reach = 2,
drops = { drops = {
{name = "mcl_core:coal_lump", {name = mobs_mc.items.coal,
chance = 1, chance = 1,
min = 0, min = 0,
max = 1, max = 1,
looting = "common",}, looting = "common",},
{name = "mcl_mobitems:bone", {name = mobs_mc.items.bone,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2, max = 2,
looting = "common",}, looting = "common",},
-- Head -- Head
{name = "mcl_heads:wither_skeleton", {name = mobs_mc.items.head_wither_skeleton,
chance = 40, -- 2.5% chance chance = 40, -- 2.5% chance
min = 1, min = 1,
max = 1, max = 1,
@ -96,21 +96,20 @@ mcl_mobs:register_mob("mobs_mc:witherskeleton", {
}) })
--spawn --spawn
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:witherskeleton", "mobs_mc:witherskeleton",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"SoulsandValley",
}, },
0, 0,
7, 7,
30, 30,
5000, 5000,
5, 5,
mcl_vars.mg_nether_min, mobs_mc.spawn_height.nether_min,
mcl_vars.mg_nether_max) mobs_mc.spawn_height.nether_max)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)

View File

@ -109,7 +109,7 @@ local slime_big = {
on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5),
use_texture_alpha = true, use_texture_alpha = true,
} }
mcl_mobs:register_mob("mobs_mc:slime_big", slime_big) mobs:register_mob("mobs_mc:slime_big", slime_big)
local slime_small = table.copy(slime_big) local slime_small = table.copy(slime_big)
slime_small.sounds.base_pitch = 1.15 slime_small.sounds.base_pitch = 1.15
@ -126,7 +126,7 @@ slime_small.run_velocity = 1.3
slime_small.jump_height = 4.3 slime_small.jump_height = 4.3
slime_small.spawn_small_alternative = "mobs_mc:slime_tiny" slime_small.spawn_small_alternative = "mobs_mc:slime_tiny"
slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0) slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0)
mcl_mobs:register_mob("mobs_mc:slime_small", slime_small) mobs:register_mob("mobs_mc:slime_small", slime_small)
local slime_tiny = table.copy(slime_big) local slime_tiny = table.copy(slime_big)
slime_tiny.sounds.base_pitch = 1.3 slime_tiny.sounds.base_pitch = 1.3
@ -140,7 +140,7 @@ slime_tiny.damage = 0
slime_tiny.reach = 2.5 slime_tiny.reach = 2.5
slime_tiny.drops = { slime_tiny.drops = {
-- slimeball -- slimeball
{name = "mcl_mobitems:slimeball", {name = mobs_mc.items.slimeball,
chance = 1, chance = 1,
min = 0, min = 0,
max = 2,}, max = 2,},
@ -151,12 +151,12 @@ slime_tiny.jump_height = 3
slime_tiny.spawn_small_alternative = nil slime_tiny.spawn_small_alternative = nil
slime_tiny.on_die = nil slime_tiny.on_die = nil
mcl_mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) mobs:register_mob("mobs_mc:slime_tiny", slime_tiny)
local smin = mcl_vars.mg_overworld_min local smin = mobs_mc.spawn_height.overworld_min
local smax = mobs_mc.water_level - 23 local smax = mobs_mc.spawn_height.water - 23
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:slime_tiny", "mobs_mc:slime_tiny",
"overworld", "overworld",
"ground", "ground",
@ -200,7 +200,7 @@ minetest.LIGHT_MAX+1,
smin, smin,
smax) smax)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:slime_small", "mobs_mc:slime_small",
"overworld", "overworld",
"ground", "ground",
@ -244,7 +244,7 @@ minetest.LIGHT_MAX+1,
smin, smin,
smax) smax)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:slime_big", "mobs_mc:slime_big",
"overworld", "overworld",
"ground", "ground",
@ -315,7 +315,7 @@ local magma_cube_big = {
reach = 3, reach = 3,
armor = 53, armor = 53,
drops = { drops = {
{name = "mcl_mobitems:magma_cream", {name = mobs_mc.items.magma_cream,
chance = 4, chance = 4,
min = 1, min = 1,
max = 1,}, max = 1,},
@ -348,7 +348,7 @@ local magma_cube_big = {
on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5), on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5),
fire_resistant = true, fire_resistant = true,
} }
mcl_mobs:register_mob("mobs_mc:magma_cube_big", magma_cube_big) mobs:register_mob("mobs_mc:magma_cube_big", magma_cube_big)
local magma_cube_small = table.copy(magma_cube_big) local magma_cube_small = table.copy(magma_cube_big)
magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small" magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small"
@ -369,7 +369,7 @@ magma_cube_small.reach = 2.75
magma_cube_small.armor = 66 magma_cube_small.armor = 66
magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny" magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny"
magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0) magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0)
mcl_mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small) mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small)
local magma_cube_tiny = table.copy(magma_cube_big) local magma_cube_tiny = table.copy(magma_cube_big)
magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small" magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small"
@ -391,19 +391,18 @@ magma_cube_tiny.drops = {}
magma_cube_tiny.spawn_small_alternative = nil magma_cube_tiny.spawn_small_alternative = nil
magma_cube_tiny.on_die = nil magma_cube_tiny.on_die = nil
mcl_mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
local mmin = mcl_vars.mg_nether_min local mmin = mobs_mc.spawn_height.nether_min
local mmax = mcl_vars.mg_nether_max local mmax = mobs_mc.spawn_height.nether_max
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:magma_cube_tiny", "mobs_mc:magma_cube_tiny",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"BasaltDelta",
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
@ -414,13 +413,12 @@ mmin,
mmax) mmax)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:magma_cube_small", "mobs_mc:magma_cube_small",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"BasaltDelta",
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
@ -430,13 +428,12 @@ minetest.LIGHT_MAX+1,
mmin, mmin,
mmax) mmax)
mcl_mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:magma_cube_big", "mobs_mc:magma_cube_big",
"nether", "nether",
"ground", "ground",
{ {
"Nether", "Nether"
"BasaltDelta",
}, },
0, 0,
minetest.LIGHT_MAX+1, minetest.LIGHT_MAX+1,
@ -446,6 +443,11 @@ minetest.LIGHT_MAX+1,
mmin, mmin,
mmax) mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
-- spawn eggs -- spawn eggs
mcl_mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png") mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png")
mcl_mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png") mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png")

View File

@ -20,7 +20,7 @@ local gotten_texture = {
"blank.png", "blank.png",
} }
mcl_mobs:register_mob("mobs_mc:snowman", { mobs:register_mob("mobs_mc:snowman", {
description = S("Snow Golem"), description = S("Snow Golem"),
type = "npc", type = "npc",
spawn_class = "passive", spawn_class = "passive",
@ -52,7 +52,7 @@ mcl_mobs:register_mob("mobs_mc:snowman", {
"farming_pumpkin_top.png", --left "farming_pumpkin_top.png", --left
}, },
gotten_texture = gotten_texture, gotten_texture = gotten_texture,
drops = {{ name = "mcl_throwing:snowball", chance = 1, min = 0, max = 15 }}, drops = {{ name = mobs_mc.items.snowball, chance = 1, min = 0, max = 15 }},
visual_size = {x=3, y=3}, visual_size = {x=3, y=3},
walk_velocity = 0.6, walk_velocity = 0.6,
run_velocity = 2, run_velocity = 2,
@ -106,7 +106,7 @@ mcl_mobs:register_mob("mobs_mc:snowman", {
local belowdef = minetest.registered_nodes[minetest.get_node(below).name] local belowdef = minetest.registered_nodes[minetest.get_node(below).name]
if belowdef and belowdef.walkable and (belowdef.node_box == nil or belowdef.node_box.type == "regular") then if belowdef and belowdef.walkable and (belowdef.node_box == nil or belowdef.node_box.type == "regular") then
-- Place top snow -- Place top snow
minetest.set_node(pos, {name = "mcl_core:snow"}) minetest.set_node(pos, {name = mobs_mc.items.top_snow})
end end
end end
end end
@ -114,7 +114,7 @@ mcl_mobs:register_mob("mobs_mc:snowman", {
-- Remove pumpkin if using shears -- Remove pumpkin if using shears
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
if self.gotten ~= true and item:get_name() == "mcl_tools:shears" then if self.gotten ~= true and item:get_name() == mobs_mc.items.shears then
-- Remove pumpkin -- Remove pumpkin
self.gotten = true self.gotten = true
self.object:set_properties({ self.object:set_properties({
@ -130,7 +130,7 @@ mcl_mobs:register_mob("mobs_mc:snowman", {
-- Wear out -- Wear out
if not minetest.is_creative_enabled(clicker:get_player_name()) then 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) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
end end
end end
@ -160,7 +160,7 @@ end
-- This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function -- This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function
-- of the node. -- of the node.
-- This summons a snow golen when pos is next to a row of two snow blocks. -- This summons a snow golen when pos is next to a row of two snow blocks.
function mobs_mc.check_snow_golem_summon(pos) mobs_mc.tools.check_snow_golem_summon = function(pos)
local checks = { local checks = {
-- These are the possible placement patterns -- These are the possible placement patterns
-- { snow block pos. 1, snow block pos. 2, snow golem spawn position } -- { snow block pos. 1, snow block pos. 2, snow golem spawn position }
@ -178,7 +178,7 @@ function mobs_mc.check_snow_golem_summon(pos)
local place = checks[c][3] local place = checks[c][3]
local b1n = minetest.get_node(b1) local b1n = minetest.get_node(b1)
local b2n = minetest.get_node(b2) local b2n = minetest.get_node(b2)
if b1n.name == "mcl_core:snowblock" and b2n.name == "mcl_core:snowblock" then if b1n.name == mobs_mc.items.snow_block and b2n.name == mobs_mc.items.snow_block then
-- Remove the pumpkin and both snow blocks and summon the snow golem -- Remove the pumpkin and both snow blocks and summon the snow golem
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.remove_node(b1) minetest.remove_node(b1)
@ -196,4 +196,4 @@ function mobs_mc.check_snow_golem_summon(pos)
end end
-- Spawn egg -- Spawn egg
mcl_mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0) mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0)

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