Compare commits

..

1 Commits

Author SHA1 Message Date
cora d60fa0f4ab Add /enderdebug command to study staring detection 2022-05-31 23:31:01 +02:00
550 changed files with 2117 additions and 12759 deletions

2
API.md
View File

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

View File

@ -27,11 +27,6 @@
* Code-Sploit
* NO11
* kabou
* rudzik8
* chmodsayshello
* PrarieWind
* RandomLegoBrick
* SumianVoice
## Contributors
* Laurent Rocher
@ -76,12 +71,6 @@
* Sven792
* aldum
* Dieter44
* Pepebotella
* MrRar
* Lazerbeak12345
* mrminer
* Thunder1035
* opfromthestart
## MineClone5
* kay27
@ -89,12 +78,10 @@
* epCode
* NO11
* j45
* chmodsayshello
* 3raven
* PrarieWind
* Gustavo1
* CableGuy67
* MrRar
## Mineclonia
* erlehmann
@ -147,9 +134,6 @@
* yutyo
* NO11
* kay27
* MysticTempest
* RandomLegoBrick
* cora
## Translations
* Wuzzy
@ -159,8 +143,6 @@
* pitchum
* todoporlalibertad
* Marcin Serwin
* Pepebotella
* Emojigit
## Funders
* 40W
@ -168,6 +150,5 @@
## Special thanks
* celeron55 for creating Minetest
* Jordach for the jukebox music compilation from Big Freaking Dig
* wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues.
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
* Notch and Jeb for being the major forces behind Minecraft

View File

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

View File

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

View File

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

View File

@ -161,9 +161,9 @@ minetest.register_on_dieplayer(function(player, mt_reason)
if mt_reason.approved then
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
end
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
end)
minetest.register_on_mods_loaded(function()
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
end)

View File

@ -337,6 +337,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
if not obj:is_player() then
return
end
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
obj:add_velocity(vector.multiply(punch_dir, impact * 20))

View File

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

View File

@ -13,21 +13,11 @@ local function is_group(pos, group)
end
local is_water = flowlib.is_water
local function is_river_water(p)
local n = minetest.get_node(p).name
if n == "mclx_core:river_water_source" or n == "mclx_core:river_water_flowing" then
return true
end
end
local function is_ice(pos)
return is_group(pos, "ice")
end
local function is_fire(pos)
return is_group(pos, "set_on_fire")
end
local function get_sign(i)
if i == 0 then
return 0
@ -120,11 +110,9 @@ end
local boat = {
physical = true,
pointable = true,
-- Warning: Do not change the position of the collisionbox top surface,
-- lowering it causes the boat to fall through the world if underwater
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7},
visual = "mesh",
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"},
@ -206,8 +194,6 @@ end
function boat.on_step(self, dtime, moveresult)
mcl_burning.tick(self.object, dtime, self)
-- mcl_burning.tick may remove object immediately
if not self.object:get_pos() then return end
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
local v_factor = 1
@ -216,21 +202,16 @@ function boat.on_step(self, dtime, moveresult)
local on_water = true
local on_ice = false
local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
local in_river_water = is_river_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z}
if not is_water(waterp) then
on_water = false
if not in_water and is_ice(waterp) then
on_ice = true
elseif is_fire({x=p.x, y=p.y-boat_y_offset, z=p.z}) then
boat.on_death(self, nil)
self.object:remove()
return
else
v_slowdown = 0.04
v_factor = 0.5
end
elseif in_water and not in_river_water then
elseif in_water then
on_water = false
in_water = true
v_factor = 0.75
@ -362,18 +343,7 @@ function boat.on_step(self, dtime, moveresult)
else
p.y = p.y + 1
local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian"
if is_river_water(p) then
local y = self.object:get_velocity().y
if y >= 5 then
y = 5
elseif y < 0 then
new_acce = {x = 0, y = 10, z = 0}
else
new_acce = {x = 0, y = 2, z = 0}
end
new_velo = get_velocity(self._v, self.object:get_yaw(), y)
self.object:set_pos(self.object:get_pos())
elseif is_water(p) and not is_river_water(p) or is_obsidian_boat then
if is_water(p) or is_obsidian_boat then
-- Inside water: Slowly sink
local y = self.object:get_velocity().y
y = y - 0.01

View File

@ -9,5 +9,4 @@ Oak Boat=Bateau en Chêne
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
Spruce Boat=Bateau en Sapin
Water vehicle=Véhicule aquatique
Sneak to dismount=Se baisser pour descendre
Obsidian Boat=Bateau en Obsidienne
Sneak to dismount=

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -91,7 +91,7 @@ minetest.register_chatcommand("clearmobs",{
if o.is_mob then
if param == "all" or
( param == "nametagged" and o.nametag ) or
( param == "" and ( not o.nametag or o.nametag == "" ) and not o.tamed ) or
( param == "" and not o.nametag and not o.tamed ) or
( num and num > 0 and vector.distance(p:get_pos(),o.object:get_pos()) <= num ) then
o.object:remove()
end
@ -213,11 +213,11 @@ end
local collision = function(self)
local pos = self.object:get_pos()
if not pos then return {0,0} end
local vel = self.object:get_velocity()
local x = 0
local z = 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
local ent = object:get_luaentity()
@ -248,20 +248,18 @@ local set_velocity = function(self, v)
end
-- halt mob if it has been ordered to stay
if self.order == "stand" or self.order == "sit" then
if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0})
return
end
local yaw = (self.object:get_yaw() or 0) + self.rotate
local vv = self.object:get_velocity()
if vv then
self.object:set_velocity({
x = (sin(yaw) * -v) + c_x,
y = vv.y,
z = (cos(yaw) * v) + c_y,
})
end
self.object:set_velocity({
x = (sin(yaw) * -v) + c_x,
y = self.object:get_velocity().y,
z = (cos(yaw) * v) + c_y,
})
end
@ -300,13 +298,9 @@ local function update_roll(self)
if is_Fleckenstein then
cbox[2], cbox[5] = -cbox[5], -cbox[2]
self.object:set_properties({collisionbox = cbox})
-- This leads to child mobs having the wrong collisionbox
-- and seeing as it seems to be nothing but an easter egg
-- i've put it inside the if. Which just makes it be upside
-- down lol.
end
self.object:set_properties({collisionbox = cbox})
end
-- set and return valid yaw
@ -409,15 +403,15 @@ local set_animation = function(self, anim, fixed_frame)
if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end
self._current_animation = self._current_animation or ""
self.animation.current = self.animation.current or ""
if (anim == self._current_animation
if (anim == self.animation.current
or not self.animation[anim .. "_start"]
or not self.animation[anim .. "_end"]) and self.state ~= "die" then
return
end
self._current_animation = anim
self.animation.current = anim
local a_start = self.animation[anim .. "_start"]
local a_end
@ -1907,11 +1901,13 @@ local specific_attack = function(list, what)
return false
end
-- find someone to attack
-- monster find someone to attack
local monster_attack = function(self)
if not damage_enabled
if self.type ~= "monster"
or not damage_enabled
or minetest.is_creative_enabled("")
or self.passive ~= false
or self.passive
or self.state == "attack"
or day_docile(self) then
return
@ -1927,9 +1923,10 @@ local monster_attack = function(self)
for n = 1, #objs do
if objs[n]:is_player() then
if mcl_mobs.invis[ objs[n]:get_player_name() ] or (not object_in_range(self, objs[n])) then
type = ""
elseif (self.type == "monster" or self._aggro) then
else
player = objs[n]
type = "player"
name = "player"
@ -2286,9 +2283,6 @@ end
local function go_to_pos(entity,b)
if not entity then return end
local s=entity.object:get_pos()
if not b then
--self.state = "stand"
return end
if vector.distance(b,s) < 1 then
--set_velocity(entity,0)
return true
@ -2311,52 +2305,15 @@ local function check_doors(self)
local def = minetest.registered_nodes[n.name]
local closed = n.name:find("_b_1")
if t < 0.3 or t > 0.8 then
if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end
if not closed then def.on_rightclick(d,n,self) end
else
if closed and def.on_rightclick then def.on_rightclick(d,n,self) end
if closed then def.on_rightclick(d,n,self) end
end
end
end
end
local gowp_etime = 0
local function check_gowp(self,dtime)
gowp_etime = gowp_etime + dtime
if gowp_etime < 0.2 then return end
gowp_etime = 0
local p = self.object:get_pos()
if not p or not self._target then return end
if vector.distance(p,self._target) < 1 then
self.waypoints = nil
self._target = nil
self.current_target = nil
self.state = "stand"
if self.callback_arrived then return self.callback_arrived(self) end
return true
end
if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then
self.current_target = table.remove(self.waypoints, 1)
--minetest.log("nextwp:".. tostring(self.current_target) )
go_to_pos(self,self.current_target)
return
elseif self.current_target then
go_to_pos(self,self.current_target)
end
if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then
self.waypoints=minetest.find_path(p,self._target,150,1,4)
if not self.waypoints then self.state = "walk" end --give up
self.current_target = nil
return
end
if not self.current_target then
--minetest.log("no path")
self.state = "walk"
end
end
-- execute current state (stand, walk, run, attacks)
-- returns true if mob has died
local do_states = function(self, dtime)
@ -2369,8 +2326,9 @@ local do_states = function(self, dtime)
local s = self.object:get_pos()
local objs = minetest.get_objects_inside_radius(s, 3)
local lp
for n = 1, #objs do
if objs[n]:is_player() then
lp = objs[n]:get_pos()
break
@ -2378,7 +2336,7 @@ local do_states = function(self, dtime)
end
-- look at any players nearby, otherwise turn randomly
if lp and self.look_at_players then
if self.look_at_players then
local vec = {
x = lp.x - s.x,
@ -2394,13 +2352,9 @@ local do_states = function(self, dtime)
yaw = set_yaw(self, yaw, 8)
end
if self.order == "sit" then
set_animation(self, "sit")
set_velocity(self, 0)
else
set_animation(self, "stand")
set_velocity(self, 0)
end
set_velocity(self, 0)
set_animation(self, "stand")
-- npc's ordered to stand stay standing
if self.type ~= "npc"
@ -2418,7 +2372,32 @@ local do_states = function(self, dtime)
end
elseif self.state == "gowp" then
check_gowp(self,dtime)
local p = self.object:get_pos()
if not p or not self._target then return end
if vector.distance(p,self._target) < 2 or ( self.waypoints and #self.waypoints == 0 ) then
self.waypoints = nil
self._target = nil
self.current_target = nil
self.state = "walk"
if self.callback_arrived then return self.callback_arrived(self) end
return true
end
if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 1.5 ) then
self.current_target = table.remove(self.waypoints, 1)
--minetest.log("nextwp:".. tostring(self.current_target) )
elseif self.current_target then
go_to_pos(self,self.current_target)
end
if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then
self.waypoints=minetest.find_path(p,self._target,150,1,4)
self.current_target = nil
return
end
if not self.current_target then
--minetest.log("no path")
self.state = "walk"
end
elseif self.state == "walk" then
local s = self.object:get_pos()
@ -2929,12 +2908,7 @@ local plane_adjacents = {
vector.new(0,0,-1),
}
local gopath_last = os.time()
function mcl_mobs:gopath(self,target,callback_arrived)
if os.time() - gopath_last < 15 then return end
gopath_last = os.time()
--minetest.log("gowp")
local p = self.object:get_pos()
local t = vector.offset(target,0,1,0)
local wp = minetest.find_path(p,t,150,1,4)
@ -2954,15 +2928,11 @@ function mcl_mobs:gopath(self,target,callback_arrived)
if wp and #wp > 0 then
self._target = t
self.callback_arrived = callback_arrived
table.remove(wp,1)
self.waypoints = wp
self.state = "gowp"
return true
else
self.state = "walk"
self.waypoints = nil
self.current_target = nil
-- minetest.log("no path found")
--minetest.log("no path found")
end
end
@ -2994,7 +2964,7 @@ local function damage_mob(self,reason,damage)
if damage > 0 then
self.health = self.health - damage
effect(self.object:get_pos(), 5, "mcl_particles_smoke.png", 1, 2, 2, nil)
effect(pos, 5, "mcl_particles_smoke.png", 1, 2, 2, nil)
if check_for_death(self, reason, {type = reason}) then
return true
@ -3004,7 +2974,6 @@ end
local function check_entity_cramming(self)
local p = self.object:get_pos()
if not p then return end
local oo = minetest.get_objects_inside_radius(p,1)
local mobs = {}
for _,o in pairs(oo) do
@ -3241,36 +3210,35 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
local die = false
-- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately.
if damage >= 0.1 then
if damage >= 0 then
-- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately.
if damage >= 0.1 then
-- weapon sounds
if weapon:get_definition().sounds ~= nil then
-- weapon sounds
if weapon:get_definition().sounds ~= nil then
local s = random(0, #weapon:get_definition().sounds)
local s = random(0, #weapon:get_definition().sounds)
minetest.sound_play(weapon:get_definition().sounds[s], {
object = self.object, --hitter,
max_hear_distance = 8
}, true)
else
minetest.sound_play("default_punch", {
object = self.object,
max_hear_distance = 5
}, true)
end
damage_effect(self, damage)
-- do damage
self.health = self.health - damage
-- skip future functions if dead, except alerting others
if check_for_death(self, "hit", {type = "punch", puncher = hitter}) then
die = true
end
minetest.sound_play(weapon:get_definition().sounds[s], {
object = self.object, --hitter,
max_hear_distance = 8
}, true)
else
minetest.sound_play("default_punch", {
object = self.object,
max_hear_distance = 5
}, true)
end
damage_effect(self, damage)
-- do damage
self.health = self.health - damage
-- skip future functions if dead, except alerting others
if check_for_death(self, "hit", {type = "punch", puncher = hitter}) then
die = true
end
-- knock back effect (only on full punch)
if not die
and self.knock_back
@ -3350,11 +3318,11 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
and (self.child == false or self.type == "monster")
and hitter:get_player_name() ~= self.owner
and not mcl_mobs.invis[ name ] then
if not die then
-- attack whoever punched mob
self.state = ""
do_attack(self, hitter)
self._aggro= true
end
-- alert others to the attack
@ -3366,6 +3334,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
obj = objs[n]:get_luaentity()
if obj then
-- only alert members of same mob or friends
if obj.group_attack
and obj.state ~= "attack"
@ -3375,7 +3344,6 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
elseif type(obj.group_attack) == "table" then
for i=1, #obj.group_attack do
if obj.name == obj.group_attack[i] then
obj._aggro = true
do_attack(obj, hitter)
break
end
@ -3470,10 +3438,7 @@ local mob_activate = function(self, staticdata, def, dtime)
def.textures = {def.textures}
end
local c = 1
if #def.textures > c then c = #def.textures end
self.base_texture = def.textures[math.random(c)]
self.base_texture = def.textures[random(1, #def.textures)]
self.base_mesh = def.mesh
self.base_size = self.visual_size
self.base_colbox = self.collisionbox
@ -3605,27 +3570,12 @@ local mob_activate = function(self, staticdata, def, dtime)
end
end
local function check_aggro(self,dtime)
if not self._aggro or not self.attack then return end
if not self._check_aggro_timer or self._check_aggro_timer > 5 then
self._check_aggro_timer = 0
if not self.attack:get_pos() or vector.distance(self.attack:get_pos(),self.object:get_pos()) > 128 then
self._aggro = nil
self.attack = nil
self.state = "stand"
end
end
self._check_aggro_timer = self._check_aggro_timer + dtime
end
-- main mob function
local mob_step = function(self, dtime)
check_item_pickup(self)
check_aggro(self,dtime)
if not self.fire_resistant then
mcl_burning.tick(self.object, dtime, self)
-- mcl_burning.tick may remove object immediately
if not self.object:get_pos() then return end
end
local pos = self.object:get_pos()
@ -3954,7 +3904,7 @@ minetest.register_entity(name, {
xp_max = def.xp_max or 0,
xp_timestamp = 0,
breath_max = def.breath_max or 15,
breathes_in_water = def.breathes_in_water or false,
breathes_in_water = def.breathes_in_water or false,
physical = true,
collisionbox = collisionbox,
selectionbox = def.selectionbox or def.collisionbox,
@ -4042,7 +3992,6 @@ minetest.register_entity(name, {
teleport = teleport,
do_teleport = def.do_teleport,
spawn_class = def.spawn_class,
can_spawn = def.can_spawn,
ignores_nametag = def.ignores_nametag or false,
rain_damage = def.rain_damage or 0,
glow = def.glow,
@ -4059,8 +4008,6 @@ minetest.register_entity(name, {
fire_resistant = def.fire_resistant or false,
fire_damage_resistant = def.fire_damage_resistant or false,
ignited_by_sunlight = def.ignited_by_sunlight or false,
spawn_in_group = def.spawn_in_group,
spawn_in_group_min = def.spawn_in_group_min,
-- End of MCL2 extensions
on_spawn = def.on_spawn,
@ -4386,73 +4333,77 @@ end
-- feeding, taming and breeding (thanks blert2112)
function mcl_mobs:feed_tame(self, clicker, feed_count, breed, tame, notake)
function mcl_mobs:feed_tame(self, clicker, feed_count, breed, tame)
if not self.follow then
return false
end
-- can eat/tame with item in hand
if self.nofollow or follow_holding(self, clicker) then
local consume_food = false
-- tame if not still a baby
-- if not in creative then take item
if not minetest.is_creative_enabled(clicker:get_player_name()) then
if tame and not self.child then
if not self.owner or self.owner == "" then
self.tamed = true
self.owner = clicker:get_player_name()
consume_food = true
end
local item = clicker:get_wielded_item()
item:take_item()
clicker:set_wielded_item(item)
end
-- increase health
mob_sound(self, "eat", nil, true)
if self.health < self.hp_max and not consume_food then
consume_food = true
self.health = min(self.health + 4, self.hp_max)
-- increase health
self.health = self.health + 4
if self.health >= self.hp_max then
self.health = self.hp_max
if self.htimer < 1 then
self.htimer = 5
end
self.object:set_hp(self.health)
end
-- make children grow quicker
if not consume_food and self.child == true then
consume_food = true
-- deduct 10% of the time to adulthood
self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1)
end
-- breed animals
if breed and not consume_food and self.hornytimer == 0 and not self.horny then
self.food = (self.food or 0) + 1
consume_food = true
if self.food >= feed_count then
self.food = 0
self.horny = true
end
end
self.object:set_hp(self.health)
update_tag(self)
-- play a sound if the animal used the item and take the item if not in creative
if consume_food then
-- don't consume food if clicker is in creative
if not minetest.is_creative_enabled(clicker:get_player_name()) and not notake then
local item = clicker:get_wielded_item()
item:take_item()
clicker:set_wielded_item(item)
end
-- always play the eat sound if food is used, even in creative
mob_sound(self, "eat", nil, true)
else
-- make sound when the mob doesn't want food
-- make children grow quicker
if self.child == true then
-- deduct 10% of the time to adulthood
self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1)
return true
end
-- feed and tame
self.food = (self.food or 0) + 1
if self.food >= feed_count then
self.food = 0
if breed and self.hornytimer == 0 then
self.horny = true
end
if tame then
self.tamed = true
if not self.owner or self.owner == "" then
self.owner = clicker:get_player_name()
end
end
-- make sound when fed so many times
mob_sound(self, "random", true)
end
return true
end
return false
end
@ -4502,6 +4453,31 @@ function mcl_mobs:spawn_child(pos, mob_type)
return child
end
-- compatibility function for old entities to new modpack entities
function mcl_mobs:alias_mob(old_name, new_name)
-- spawn egg
minetest.register_alias(old_name, new_name)
-- entity
minetest.register_entity(":" .. old_name, {
physical = false,
on_step = function(self)
if minetest.registered_entities[new_name] then
minetest.add_entity(self.object:get_pos(), new_name)
end
self.object:remove()
end
})
end
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime

View File

@ -15,7 +15,7 @@ local math_cos = math.cos
local math_sin = math.sin
local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end
local vector_distance = vector.distance
--local vector_distance = vector.distance
local vector_new = vector.new
local vector_floor = vector.floor
@ -23,18 +23,9 @@ 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
local aoc_range = 136
local mob_cap = {
monster = 70,
animal =10,
ambient =15,
water = 5, --currently unused
water_ambient = 20, --currently unused
}
-- range for mob count
local aoc_range = 32
--do mobs spawn?
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
@ -72,7 +63,6 @@ local list_of_all_biomes = {
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"MangroveSwamp_underground",
-- ocean:
@ -136,8 +126,6 @@ local list_of_all_biomes = {
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"MangroveSwamp_ocean",
"MangroveSwamp_deep_ocean",
-- water or beach?
@ -161,15 +149,10 @@ local list_of_all_biomes = {
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MangroveSwamp_shore",
-- dimension biome:
"Nether",
"BasaltDelta",
"CrimsonForest",
"WarpedForest",
"SoulsandValley",
"End",
-- Overworld regular:
@ -179,8 +162,6 @@ local list_of_all_biomes = {
"Swampland",
"Taiga",
"ExtremeHills",
"ExtremeHillsM",
"ExtremeHills+_snowtop",
"Jungle",
"Savanna",
"BirchForest",
@ -199,6 +180,7 @@ local list_of_all_biomes = {
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
@ -207,30 +189,14 @@ local list_of_all_biomes = {
"MesaBryce",
"JungleEdge",
"SavannaM",
"MangroveSwamp",
}
-- count how many mobs are in an area
local function count_mobs(pos,r,mob_type)
local function count_mobs(pos)
local num = 0
for _,l in pairs(minetest.luaentities) do
if l and l.is_mob and (mob_type == nil or l.type == mob_type) then
local p = l.object:get_pos()
if p and vector_distance(p,pos) < r then
num = num + 1
end
end
end
return num
end
local function count_mobs_total(mob_type)
local num = 0
for _,l in pairs(minetest.luaentities) do
if l.is_mob then
if mob_type == nil or l.type == mob_type then
num = num + 1
end
for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do
if object and object:get_luaentity() and object:get_luaentity().is_mob then
num = num + 1
end
end
return num
@ -323,7 +289,7 @@ function mcl_mobs:spawn_setup(def)
spawn_dictionary[#spawn_dictionary + 1] = {
name = name,
dimension = dimension,
type_of_spawning = type_of_spawning,
type_of_spawning = type_of_spawning,
biomes = biomes,
min_light = min_light,
max_light = max_light,
@ -410,94 +376,13 @@ local function is_farm_animal(n)
return n == "mobs_mc:pig" or n == "mobs_mc:cow" or n == "mobs_mc:sheep" or n == "mobs_mc:chicken" or n == "mobs_mc:horse" or n == "mobs_mc:donkey"
end
local function get_water_spawn(p)
local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"})
if nn and #nn > 0 then
return nn[math.random(#nn)]
end
end
local function 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 dimension = dimension or mcl_worlds.pos_to_dimension(pos)
local goal_pos = get_next_mob_spawn_pos(pos)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
local spawning_position_list = find_nodes_in_area_under_air(
{x = goal_pos.x, y = y_min, z = goal_pos.z},
{x = goal_pos.x, y = y_max, z = goal_pos.z},
@ -506,10 +391,41 @@ if mobs_spawn then
if #spawning_position_list <= 0 then return end
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
--hard code mob limit in area to 5 for now
if count_mobs(spawning_position) >= 5 then return end
local gotten_node = get_node(spawning_position).name
local gotten_biome = minetest.get_biome_data(spawning_position)
if not gotten_node or not gotten_biome then return end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
--add this so mobs don't spawn inside nodes
spawning_position.y = spawning_position.y + 1
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(spawning_position)
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
local is_ground = not (is_water or is_lava)
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
local has_bed = minetest.find_node_near(pos,25,{"group:bed"})
if not is_ground then
spawning_position.y = spawning_position.y - 1
end
local mob_def
--create a disconnected clone of the spawn dictionary
--prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
local noise = perlin_noise:get_3d(spawning_position)
local current_summary_chance = summary_chance
table.shuffle(mob_library_worker_table)
while #mob_library_worker_table > 0 do
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
local mob_index = 1
@ -521,30 +437,23 @@ if mobs_spawn then
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
if mob_def
and spawning_position.y >= mob_def.min_height
and spawning_position.y <= mob_def.max_height
and mob_def.dimension == dimension
and biome_check(mob_def.biomes, gotten_biome)
and gotten_light >= mob_def.min_light
and gotten_light <= mob_def.max_light
and (is_ground or mob_def.type_of_spawning ~= "ground")
and (mob_def.check_position and mob_def.check_position(spawning_position) or true)
and (not is_farm_animal(mob_def.name) or is_grass)
and (mob_type ~= "npc" or has_bed)
then
--everything is correct, spawn mob
local object
if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then
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
local object = minetest.add_entity(spawning_position, mob_def.name)
if object then
return mob_def.on_spawn and mob_def.on_spawn(object, spawning_position)
return mob_def.on_spawn and mob_def.on_spawn(object, pos)
end
end
current_summary_chance = current_summary_chance - mob_chance
@ -573,14 +482,3 @@ if mobs_spawn then
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

@ -38,12 +38,6 @@ local function wither_spawn(pos)
if check_schem(p, schem) then
remove_schem(p, schem)
minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither")
local objects = minetest.get_objects_inside_radius(pos, 20)
for _, players in ipairs(objects) do
if players:is_player() then
awards.unlock(players:get_player_name(), "mcl:witheringHeights")
end
end
end
end
end
@ -52,9 +46,6 @@ 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)
minetest.after(0, wither_spawn, pointed.above)
old_on_place(itemstack, placer, pointed)
end

View File

@ -7,7 +7,6 @@ mcl_mobs:register_mob("mobs_mc:bat", {
type = "animal",
spawn_class = "ambient",
can_despawn = true,
spawn_in_group = 8,
passive = true,
hp_min = 6,
hp_max = 6,

View File

@ -16,8 +16,6 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
description = S("Blaze"),
type = "monster",
spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 3,
hp_min = 20,
hp_max = 20,
xp_min = 10,

View File

@ -74,7 +74,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
fear_height = 4,
on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
end,
@ -122,6 +122,8 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",
"SunflowerPlains",

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

View File

@ -48,7 +48,7 @@ local cow_def = {
run_end = 40,
},
on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end
if self.child then
@ -83,11 +83,9 @@ mcl_mobs:register_mob("mobs_mc:cow", cow_def)
local mooshroom_def = table.copy(cow_def)
mooshroom_def.description = S("Mooshroom")
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.on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end
if self.child then
@ -153,12 +151,17 @@ mcl_mobs:spawn_specific(
"ground",
{
"flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",

View File

@ -12,7 +12,6 @@ local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:creeper", {
type = "monster",
spawn_class = "hostile",
spawn_in_group = 1,
hp_min = 20,
hp_max = 20,
xp_min = 5,
@ -275,6 +274,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -301,6 +301,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -339,6 +340,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -348,6 +350,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -373,6 +376,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",

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

@ -35,7 +35,6 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
},
physical = true,
damage = 10,
knock_back = false,
jump = true,
jump_height = 14,
fly = true,

View File

@ -26,6 +26,8 @@
local S = minetest.get_translator("mobs_mc")
local enderdebug = false
local telesound = function(pos, is_source)
local snd
if is_source then
@ -219,7 +221,6 @@ local select_enderman_animation = function(animation_type)
end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local spawners = {}
mcl_mobs:register_mob("mobs_mc:enderman", {
description = S("Enderman"),
@ -258,48 +259,23 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
},
animation = select_enderman_animation("normal"),
_taken_node = "",
can_spawn = function(pos)
return #minetest.find_nodes_in_area(vector.offset(pos,0,1,0),vector.offset(pos,0,3,0),{"air"}) > 2
end,
do_custom = function(self, dtime)
-- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos()
if self._particle_timer and self._particle_timer >= 1 then
for _,player in pairs(minetest.get_connected_players()) do
if not spawners[player] then spawners[player] = {} end
local dst = vector.distance(player:get_pos(),enderpos)
if dst < 128 and not spawners[player][self.object] then
self._particle_timer = 0
spawners[player][self.object] = minetest.add_particlespawner({
amount = 5,
minpos = vector.new(-0.6,0,-0.6),
maxpos = vector.new(0.6,3,0.6),
minvel = vector.new(-0.25,-0.25,-0.25),
maxvel = vector.new(0.25,0.25,0.25),
minacc = vector.new(-0.5,-0.5,-0.5),
maxacc = vector.new(0.5,0.5,0.5),
minexptime = 0.2,
maxexptime = 3,
minsize = 0.2,
maxsize = 1.2,
collisiondetection = true,
vertical = false,
time = 0,
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
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
elseif not self._particle_timer then
self._particle_timer = 0
local chanceOfParticle = math.random(0, 1)
if chanceOfParticle == 1 then
minetest.add_particle({
pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2},
velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)},
acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)},
expirationtime = math.random(),
size = math.random(),
collisiondetection = true,
vertical = false,
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
})
end
self._particle_timer = self._particle_timer + dtime
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
enderpos = self.object:get_pos()
local dim = mcl_worlds.pos_to_dimension(enderpos)
if dim == "overworld" then
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
@ -335,24 +311,24 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
if self.state == "attack" then
if self.attack then
local target = self.attack
local pos = target:get_pos()
if pos ~= nil then
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
self:teleport(target)
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
--self:teleport(nil)
--self.state = ""
--else
if self.attack then
local target = self.attack
local pos = target:get_pos()
if pos ~= nil then
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
self:teleport(target)
end
end
end
end
else --if not attacking try to tp to the dark
if minetest.get_node_light(enderpos) > minetest.LIGHT_MAX then
self:teleport(nil)
end
--end
end
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby.
enderpos = self.object:get_pos()
local enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2)
for n = 1, #objs do
@ -417,11 +393,18 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
--if looking in general head position, turn hostile
if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then
self.provoked = "staring"
self.attack = minetest.get_player_by_name(obj:get_player_name())
if not enderdebug then
self.attack = minetest.get_player_by_name(obj:get_player_name())
else
minetest.log("staring")
end
break
else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez
if self.provoked == "staring" then
self.provoked = "broke_contact"
if enderdebug then
minetest.log("stopped staring")
end
end
end
@ -616,13 +599,6 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
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
mcl_mobs:spawn_specific(
@ -660,6 +636,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -686,6 +663,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -724,6 +702,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -733,6 +712,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -758,6 +738,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
@ -794,32 +775,27 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"SoulsandVall3ey",
"Nether"
},
0,
11,
7,
30,
27500,
4,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
-- Warped Forest spawn (common)
mcl_mobs:spawn_specific(
"mobs_mc:enderman",
"nether",
"ground",
{
"WarpedForest"
},
0,
11,
30,
5000,
4,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)
minetest.register_chatcommand("enderdebug",{
description = S("Toggle between enderman aggro behavior and just signal staring"),
privs = { debug = true },
func=function()
enderdebug = not enderdebug
if enderdebug then
return true, "Endermen will not attack"
end
return true, "Endermen back to normal"
end
})

View File

@ -23,7 +23,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
collisionbox = {-2, 5, -2, 2, 9, 2},
visual = "mesh",
mesh = "mobs_mc_ghast.b3d",
spawn_in_group = 1,
textures = {
{"mobs_mc_ghast.png"},
},
@ -65,14 +64,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
makes_footstep_sound = false,
instant_death = true,
fire_resistant = true,
can_spawn = function(pos)
if not minetest.get_item_group(minetest.get_node(pos).name,"solid") then return false end
local p1=vector.offset(pos,-2,1,-2)
local p2=vector.offset(pos,2,5,2)
local nn = minetest.find_nodes_in_area(p1,p2,{"air"})
if #nn< 41 then return false end
return true
end,
do_custom = function(self)
if self.firing == true then
self.base_texture = {"mobs_mc_ghast_firing.png"}
@ -90,14 +81,12 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"SoulsandValley",
"BasaltDelta",
"Nether"
},
0,
7,
minetest.LIGHT_MAX+1,
30,
72000,
18000,
2,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
@ -116,12 +105,7 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
full_punch_interval = 1.0,
damage_groups = {fleshy = 6},
}, nil)
local p = self.object:get_pos()
if p then
mcl_mobs:boom(self, p, 1, true)
else
mcl_mobs:boom(self, player:get_pos(), 1, true)
end
mcl_mobs:boom(self, self.object:get_pos(), 1, true)
end,
hit_mob = function(self, mob)

View File

@ -8,14 +8,12 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
description = S("Guardian"),
type = "monster",
spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 4,
hp_min = 30,
hp_max = 30,
xp_min = 10,
xp_max = 10,
breath_max = -1,
passive = false,
passive = false,
attack_type = "dogfight",
pathfinding = 1,
view_range = 16,

View File

@ -100,8 +100,6 @@ local horse = {
description = S("Horse"),
type = "animal",
spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 6,
visual = "mesh",
mesh = "mobs_mc_horse.b3d",
visual_size = {x=3.0, y=3.0},
@ -492,8 +490,6 @@ local d = 0.86 -- donkey scale
local donkey = table.copy(horse)
donkey.description = S("Donkey")
donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}}
donkey.spawn_in_group = 3
donkey.spawn_in_group_min = 1
donkey.animation = {
speed_normal = 25,
stand_start = 0, stand_end = 0,
@ -546,14 +542,41 @@ mcl_mobs:spawn_specific(
"ground",
{
"flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",
"SunflowerPlains",
"Taiga",
"Taiga_beach",
"Forest",
"Forest_beach",
"FlowerForest",
"FlowerForest_beach",
"BirchForest",
"BirchForestM",
"RoofedForest",
"Savanna",
"Savanna_beach",
"SavannaM",
"Savanna_beach",
"Plains_beach",
"Jungle",
"Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge",
"JungleEdgeM",
"Swampland",
"Swampland_shore"
},
0,
minetest.LIGHT_MAX+1,
@ -563,22 +586,20 @@ minetest.LIGHT_MAX+1,
mobs_mc.water_level+3,
mcl_vars.mg_overworld_max)
mcl_mobs:spawn_specific(
"mobs_mc:donkey",
"overworld",
"ground",
{
"flat",
"Plains",
"Plains_beach",
"SunflowerPlains",
"Savanna",
"Savanna_beach",
"SavannaM",
"Savanna_beach",
"Plains_beach",
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
9,
0,
minetest.LIGHT_MAX+1,
30,
15000,

View File

@ -114,7 +114,6 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i
-- Illagers and witch
dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar
dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i
@ -143,8 +142,3 @@ dofile(path .. "/slime+magma_cube.lua") -- Wuzzy
dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
dofile(path .. "/vex.lua") -- KrupnoPavel
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/cod.lua")
dofile(path .. "/salmon.lua")
dofile(path .. "/tropical_fish.lua")
dofile(path .. "/dolphin.lua")

View File

@ -37,7 +37,6 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
run_velocity = 1.2,
-- Approximation
damage = 14,
knock_back = false,
reach = 3,
group_attack = true,
attacks_monsters = true,

View File

@ -28,17 +28,11 @@ mcl_mobs:register_mob("mobs_mc:llama", {
description = S("Llama"),
type = "animal",
spawn_class = "passive",
passive = false,
attack_type = "shoot",
shoot_interval = 5.5,
arrow = "mobs_mc:llamaspit",
shoot_offset = 1, --3.5 *would* be a good value visually but it somehow messes with the projectiles trajectory
spawn_in_group_min = 4,
spawn_in_group = 6,
hp_min = 15,
hp_max = 30,
xp_min = 1,
xp_max = 3,
passive = false,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45},
visual = "mesh",
mesh = "mobs_mc_llama.b3d",
@ -51,7 +45,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
},
visual_size = {x=3, y=3},
makes_footstep_sound = true,
runaway = false,
runaway = true,
walk_velocity = 1,
run_velocity = 4.4,
follow_velocity = 4.4,
@ -217,46 +211,24 @@ mcl_mobs:register_mob("mobs_mc:llama", {
})
-- 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
mcl_mobs:spawn_specific(
"mobs_mc:llama",
"overworld",
"ground",
{
"Savanna",
"SavannaM",
"SavannaM_beach",
"Savanna_beach",
"Savanna_ocean",
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"Jungle",
"Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge",
"JungleEdgeM",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
},
0,
minetest.LIGHT_MAX+1,

View File

@ -1,58 +1,64 @@
# textdomain: mobs_mc
Agent=Agente
Bat=Murciélago
Blaze=Blaze
Chicken=Pollo
Cod=Bacalao
Cow=Vaca
Mooshroom=Champivaca
Mooshroom=Champiñaca
Creeper=Creeper
Dolphin=Delfín
Ender Dragon=Ender Dragon
Ender Dragon=Enderdragón
Enderman=Enderman
Endermite=Endermite
Ghast=Ghast
Elder Guardian=Gran guardián
Guardian=Guardián
Elder Guardian=Guardián Anciano
Donkey=Burro
Horse=Caballo
Skeleton Horse=Caballo esquelético
Zombie Horse=Caballo zombie
Donkey=Burro
Mule=Mula
Skeleton Horse=Caballo esqueleto
Zombie Horse=Caballo zombi
Iron Golem=Golem de hierro
Llama=Llama
Cat=Gato
Ocelot=Ocelote
Parrot=Loro
Pig=Cerdo
Polar Bear=Oso polar
Killer Bunny=Conejo asesino
Rabbit=Conejo
Salmon=Salmón
Killer Bunny=Conejo asesino
Sheep=Oveja
Shulker=Shulker
Silverfish=Lepisma
Skeleton=Esqueleto
Stray=Esqueleto glacial
Wither Skeleton=Esqueleto del Wither
Stray=Esqueleto
Wither Skeleton=Esqueleto wither
Magma Cube=Cubo de Magma
Slime=Slime
Snow Golem=Golem de nieve
Cave Spider=Araña de las cuevas
Spider=Araña
Cave Spider=Araña de las cuevas
Squid=Calamar
Vex=Ánima
Master=Maestro
Villager=Aldeano
Evoker=Invocador
Illusioner=Illusionista
Villager=Aldeano
Vindicator=Vindicador
Zombie Villager=Aldeano zombi
Zombie Villager=Aldeano zombie
Witch=Bruja
Wither=Wither
Wolf=Lobo
Baby Husk=Bebé Zombi Momificado
Baby Zombie=Bebé Zombi
Husk=Zombi Momificado
Zombie=Zombi
Baby Zombie Pigman=Bebé Hombrecerdo Zombi
Zombie Pigman=Hombrecerdo Zombi
Husk=Husk
Zombie=Zombie
Zombie Pigman=Cerdo Zombie
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

@ -62,8 +62,3 @@ Weapon Smith=Fabriquant d'arme
Tool Smith=Fabriquant d'outil
Cleric=Clerc
Nitwit=Crétin
Cod=Morue
Salmon=Saumon
Dolphin=Dauphin
Pillager=Pilleur
Tropical fish=Poisson tropical

View File

@ -62,8 +62,3 @@ Weapon Smith=
Tool Smith=
Cleric=
Nitwit=
Cod=
Salmon=
Dolphin=
Pillager=
Tropical fish=

View File

@ -30,8 +30,6 @@ local ocelot = {
type = "animal",
spawn_class = "passive",
can_despawn = true,
spawn_in_group = 3,
spawn_in_group_min = 1,
hp_min = 10,
hp_max = 10,
xp_min = 1,

View File

@ -13,53 +13,6 @@ local shoulders = {
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)
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"
@ -100,8 +53,7 @@ local function check_perch(self,dtime)
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
if n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0 then
o:set_detach()
self.detach_timer = 0
return
@ -127,7 +79,7 @@ end
mcl_mobs:register_mob("mobs_mc:parrot", {
description = S("Parrot"),
type = "passive",
type = "npc",
spawn_class = "passive",
pathfinding = 1,
hp_min = 6,
@ -207,7 +159,6 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
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

View File

@ -99,7 +99,7 @@ mcl_mobs:register_mob("mobs_mc:pig", {
local wielditem = clicker:get_wielded_item()
-- Feed pig
if wielditem:get_name() ~= "mcl_mobitems:carrot_on_a_stick" then
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
end
if mcl_mobs:protect(self, clicker) then return end
@ -194,12 +194,17 @@ mcl_mobs:spawn_specific(
"ground",
{
"flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",

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

@ -76,6 +76,7 @@ mcl_mobs:spawn_specific(
"ColdTaiga",
"IcePlainsSpikes",
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
minetest.LIGHT_MAX+1,

View File

@ -6,10 +6,9 @@ local rabbit = {
description = S("Rabbit"),
type = "animal",
spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 3,
passive = true,
reach = 1,
hp_min = 3,
hp_max = 3,
xp_min = 1,
@ -75,7 +74,7 @@ local rabbit = {
},
on_rightclick = function(self, clicker)
-- Feed, tame protect or capture
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end
end,
@ -133,9 +132,18 @@ mcl_mobs:spawn_specific(
"Desert",
"FlowerForest",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,

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

@ -70,8 +70,6 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
color = "unicolor_white",
makes_footstep_sound = true,
walk_velocity = 1,
runaway = true,
runaway_from = {"mobs_mc:wolf"},
drops = {
{name = "mcl_mobitems:mutton",
chance = 1,
@ -197,7 +195,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", {
on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item()
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
if mcl_mobs:protect(self, clicker) then return end
if item:get_name() == "mcl_tools:shears" and not self.gotten and not self.child then
@ -348,7 +346,7 @@ mcl_mobs:spawn_specific(
"Swampland",
"Swampland_shore"
},
9,
0,
minetest.LIGHT_MAX+1,
30,
15000,

View File

@ -33,7 +33,6 @@ mcl_mobs:register_mob("mobs_mc:shulker", {
-- TODO: Make shulker dye-able
visual_size = {x=3, y=3},
walk_chance = 0,
knock_back = false,
jump = false,
drops = {
{name = "mcl_mobitems:shulker_shell",

View File

@ -162,6 +162,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -188,6 +189,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -226,6 +228,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -235,6 +238,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -260,6 +264,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
@ -297,10 +302,10 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"SoulsandValley",
"Nether"
},
0,
minetest.LIGHT_MAX+1,
7,
30,
10000,
3,

View File

@ -101,8 +101,7 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"SoulsandValley",
"Nether"
},
0,
7,

View File

@ -402,8 +402,7 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"BasaltDelta",
"Nether"
},
0,
minetest.LIGHT_MAX+1,
@ -419,8 +418,7 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"BasaltDelta",
"Nether"
},
0,
minetest.LIGHT_MAX+1,
@ -435,8 +433,7 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
{
"Nether",
"BasaltDelta",
"Nether"
},
0,
minetest.LIGHT_MAX+1,
@ -446,6 +443,11 @@ minetest.LIGHT_MAX+1,
mmin,
mmax)
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_tiny", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_small", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_big", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
-- spawn eggs
mcl_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")

View File

@ -109,6 +109,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -135,6 +136,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -173,6 +175,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -182,6 +185,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -207,6 +211,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 919 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 932 B

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