mobs-redo #2
2
API.md
|
@ -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.
|
||||
|
|
16
CREDITS.md
|
@ -27,6 +27,10 @@
|
|||
* Code-Sploit
|
||||
* NO11
|
||||
* kabou
|
||||
* rudzik8
|
||||
* chmodsayshello
|
||||
* PrarieWind
|
||||
* RandomLegoBrick
|
||||
|
||||
## Contributors
|
||||
* Laurent Rocher
|
||||
|
@ -71,6 +75,10 @@
|
|||
* Sven792
|
||||
* aldum
|
||||
* Dieter44
|
||||
* Pepebotella
|
||||
* MrRar
|
||||
* Lazerbeak12345
|
||||
* mrminer
|
||||
|
||||
## MineClone5
|
||||
* kay27
|
||||
|
@ -78,10 +86,12 @@
|
|||
* epCode
|
||||
* NO11
|
||||
* j45
|
||||
* chmodsayshello
|
||||
* 3raven
|
||||
* PrarieWind
|
||||
* Gustavo1
|
||||
* CableGuy67
|
||||
* MrRar
|
||||
|
||||
## Mineclonia
|
||||
* erlehmann
|
||||
|
@ -134,6 +144,9 @@
|
|||
* yutyo
|
||||
* NO11
|
||||
* kay27
|
||||
* MysticTempest
|
||||
* RandomLegoBrick
|
||||
* cora
|
||||
|
||||
## Translations
|
||||
* Wuzzy
|
||||
|
@ -143,6 +156,8 @@
|
|||
* pitchum
|
||||
* todoporlalibertad
|
||||
* Marcin Serwin
|
||||
* Pepebotella
|
||||
* Emojigit
|
||||
|
||||
## Funders
|
||||
* 40W
|
||||
|
@ -150,5 +165,6 @@
|
|||
## 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
|
||||
|
|
18
README.md
|
@ -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.75 (in development)
|
||||
Version: 0.78 (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, most of **Minecraft Java
|
||||
Edition 1.12.2** features are already implemented and polishing existing
|
||||
singleplayer and multiplayer. Currently, a lot of **Minecraft Java
|
||||
Edition** features are already implemented and polishing existing
|
||||
features are prioritized over new feature requests.
|
||||
- With lessened priority yet strictly, implement features targetting
|
||||
**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported
|
||||
**Current Minecraft versions + 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,8 +108,7 @@ 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 git version of MineClone2 in production, consider using the production branch.
|
||||
It is updated weekly and contains relatively stable code for servers.
|
||||
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.
|
||||
|
||||
The following main features are available:
|
||||
|
||||
|
@ -124,7 +123,7 @@ The following main features are available:
|
|||
* Most blocks in the overworld
|
||||
* Water and lava
|
||||
* Weather
|
||||
* 28 biomes
|
||||
* 28 biomes + 5 Nether Biomes
|
||||
* The Nether, a fiery underworld in another dimension
|
||||
* Redstone circuits (partially)
|
||||
* Minecarts (partial)
|
||||
|
@ -162,7 +161,7 @@ The following features are incomplete:
|
|||
* Special minecarts
|
||||
* A couple of non-trivial blocks and items
|
||||
|
||||
Bonus features (not found in Minecraft 1.12):
|
||||
Bonus features (not found in Minecraft):
|
||||
|
||||
* 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
|
||||
|
@ -175,6 +174,9 @@ Bonus features (not found in Minecraft 1.12):
|
|||
* 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:
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
name = MineClone 2
|
||||
title = MineClone 2
|
||||
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
||||
|
|
|
@ -110,9 +110,11 @@ 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"},
|
||||
|
|
|
@ -134,6 +134,7 @@ 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
|
||||
|
|
|
@ -1,66 +1,55 @@
|
|||
-- Dripping Water Mod
|
||||
-- by kddekadenz
|
||||
|
||||
local math = math
|
||||
|
||||
-- License of code, textures & sounds: CC0
|
||||
|
||||
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,
|
||||
})
|
||||
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 = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
local function register_drop(liquid, glow, sound, nodes, interval, chance)
|
||||
minetest.register_abm({
|
||||
label = "Create drops",
|
||||
nodenames = nodes,
|
||||
neighbors = {"group:" .. liquid},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
interval = interval,
|
||||
chance = chance,
|
||||
action = function(pos)
|
||||
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)
|
||||
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
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
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"})
|
||||
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)
|
||||
|
|
|
@ -59,6 +59,8 @@ 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
|
||||
|
@ -78,7 +80,6 @@ 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
|
||||
|
@ -536,9 +537,9 @@ minetest.register_entity(":__builtin:item", {
|
|||
self.itemstring = data.itemstring
|
||||
self.always_collect = data.always_collect
|
||||
if data.age then
|
||||
self.age = data.age + dtime_s
|
||||
self.age = data.age
|
||||
else
|
||||
self.age = dtime_s
|
||||
self.age = self.age
|
||||
end
|
||||
--remember collection data
|
||||
-- If true, can collect item without delay
|
||||
|
@ -774,8 +775,8 @@ minetest.register_entity(":__builtin:item", {
|
|||
return
|
||||
end
|
||||
|
||||
-- Move item around on flowing liquids
|
||||
if def and def.liquidtype == "flowing" then
|
||||
-- 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 def.liquidtype == "flowing" or def.liquidtype == "source" 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.
|
||||
|
@ -784,11 +785,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.39
|
||||
local f = 1.2
|
||||
-- Set new item moving speed into the direciton of the liquid
|
||||
local newv = vector.multiply(vec, f)
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
|
||||
-- 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.physical_state = true
|
||||
self._flowing = true
|
||||
|
@ -808,7 +809,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then
|
||||
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and not minetest.registered_nodes[nn].groups.slippery 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
|
||||
|
|
|
@ -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 = 3.5,
|
||||
_mcl_blast_resistance = 0.7,
|
||||
_mcl_hardness = 0.7,
|
||||
after_destruct = function(pos)
|
||||
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
||||
|
|
|
@ -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 and not o.tamed ) or
|
||||
( param == "" and ( not o.nametag or 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
|
||||
|
@ -298,9 +298,13 @@ 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
|
||||
|
@ -363,6 +367,35 @@ local remove_texture_mod = function(self, mod)
|
|||
self.object:set_texture_mod(full_mod)
|
||||
end
|
||||
|
||||
-- are we flying in what we are suppose to? (taikedz)
|
||||
local flight_check = function(self)
|
||||
|
||||
local nod = self.standing_in
|
||||
local def = minetest.registered_nodes[nod]
|
||||
|
||||
if not def then return false end -- nil check
|
||||
|
||||
local fly_in
|
||||
if type(self.fly_in) == "string" then
|
||||
fly_in = { self.fly_in }
|
||||
elseif type(self.fly_in) == "table" then
|
||||
fly_in = self.fly_in
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
for _,checknode in pairs(fly_in) do
|
||||
if nod == checknode then
|
||||
return true
|
||||
elseif checknode == "__airlike" or def.walkable == false and
|
||||
(def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- set defined animation
|
||||
local set_animation = function(self, anim, fixed_frame)
|
||||
if not self.animation or not anim then
|
||||
|
@ -372,6 +405,8 @@ local set_animation = function(self, anim, fixed_frame)
|
|||
return
|
||||
end
|
||||
|
||||
if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end
|
||||
|
||||
self.animation.current = self.animation.current or ""
|
||||
|
||||
if (anim == self.animation.current
|
||||
|
@ -513,37 +548,6 @@ local line_of_sight = function(self, pos1, pos2, stepsize)
|
|||
return false
|
||||
end
|
||||
|
||||
|
||||
-- are we flying in what we are suppose to? (taikedz)
|
||||
local flight_check = function(self)
|
||||
|
||||
local nod = self.standing_in
|
||||
local def = minetest.registered_nodes[nod]
|
||||
|
||||
if not def then return false end -- nil check
|
||||
|
||||
local fly_in
|
||||
if type(self.fly_in) == "string" then
|
||||
fly_in = { self.fly_in }
|
||||
elseif type(self.fly_in) == "table" then
|
||||
fly_in = self.fly_in
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
for _,checknode in pairs(fly_in) do
|
||||
if nod == checknode then
|
||||
return true
|
||||
elseif checknode == "__airlike" and def.walkable == false and
|
||||
(def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- custom particle effects
|
||||
local effect = function(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down)
|
||||
|
||||
|
@ -1901,13 +1905,11 @@ local specific_attack = function(list, what)
|
|||
return false
|
||||
end
|
||||
|
||||
-- monster find someone to attack
|
||||
-- find someone to attack
|
||||
local monster_attack = function(self)
|
||||
|
||||
if self.type ~= "monster"
|
||||
or not damage_enabled
|
||||
if not damage_enabled
|
||||
or minetest.is_creative_enabled("")
|
||||
or self.passive
|
||||
or self.passive ~= false
|
||||
or self.state == "attack"
|
||||
or day_docile(self) then
|
||||
return
|
||||
|
@ -1923,10 +1925,9 @@ 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 = ""
|
||||
else
|
||||
elseif (self.type == "monster" or self._aggro) then
|
||||
player = objs[n]
|
||||
type = "player"
|
||||
name = "player"
|
||||
|
@ -2283,6 +2284,9 @@ 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
|
||||
|
@ -2305,15 +2309,52 @@ 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 then def.on_rightclick(d,n,self) end
|
||||
if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end
|
||||
else
|
||||
if closed then def.on_rightclick(d,n,self) end
|
||||
if closed and def.on_rightclick 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)
|
||||
|
@ -2326,9 +2367,8 @@ 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
|
||||
|
@ -2336,7 +2376,7 @@ local do_states = function(self, dtime)
|
|||
end
|
||||
|
||||
-- look at any players nearby, otherwise turn randomly
|
||||
if self.look_at_players then
|
||||
if lp and self.look_at_players then
|
||||
|
||||
local vec = {
|
||||
x = lp.x - s.x,
|
||||
|
@ -2372,32 +2412,7 @@ local do_states = function(self, dtime)
|
|||
end
|
||||
|
||||
elseif self.state == "gowp" then
|
||||
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
|
||||
check_gowp(self,dtime)
|
||||
|
||||
elseif self.state == "walk" then
|
||||
local s = self.object:get_pos()
|
||||
|
@ -2908,7 +2923,12 @@ 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)
|
||||
|
@ -2928,11 +2948,15 @@ 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
|
||||
--minetest.log("no path found")
|
||||
self.state = "walk"
|
||||
self.waypoints = nil
|
||||
self.current_target = nil
|
||||
-- minetest.log("no path found")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2964,7 +2988,7 @@ local function damage_mob(self,reason,damage)
|
|||
if damage > 0 then
|
||||
self.health = self.health - damage
|
||||
|
||||
effect(pos, 5, "mcl_particles_smoke.png", 1, 2, 2, nil)
|
||||
effect(self.object:get_pos(), 5, "mcl_particles_smoke.png", 1, 2, 2, nil)
|
||||
|
||||
if check_for_death(self, reason, {type = reason}) then
|
||||
return true
|
||||
|
@ -3210,35 +3234,36 @@ 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
|
||||
|
||||
-- weapon sounds
|
||||
if weapon:get_definition().sounds ~= nil 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
|
||||
|
||||
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)
|
||||
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
|
||||
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
|
||||
|
@ -3318,11 +3343,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
|
||||
|
@ -3334,7 +3359,6 @@ 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"
|
||||
|
@ -3344,6 +3368,7 @@ 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
|
||||
|
@ -3570,10 +3595,23 @@ 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)
|
||||
end
|
||||
|
@ -3904,7 +3942,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,
|
||||
|
@ -4008,6 +4046,8 @@ 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,
|
||||
|
@ -4333,77 +4373,74 @@ end
|
|||
|
||||
|
||||
-- feeding, taming and breeding (thanks blert2112)
|
||||
function mcl_mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
function mcl_mobs:feed_tame(self, clicker, feed_count, breed, tame, notake)
|
||||
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
|
||||
|
||||
-- if not in creative then take item
|
||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||
-- tame if not still a baby
|
||||
|
||||
local item = clicker:get_wielded_item()
|
||||
|
||||
item:take_item()
|
||||
|
||||
clicker:set_wielded_item(item)
|
||||
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
|
||||
end
|
||||
|
||||
mob_sound(self, "eat", nil, true)
|
||||
|
||||
-- increase health
|
||||
self.health = self.health + 4
|
||||
|
||||
if self.health >= self.hp_max then
|
||||
|
||||
self.health = self.hp_max
|
||||
if self.health < self.hp_max and not consume_food then
|
||||
consume_food = true
|
||||
self.health = min(self.health + 4, self.hp_max)
|
||||
|
||||
if self.htimer < 1 then
|
||||
self.htimer = 5
|
||||
end
|
||||
self.object:set_hp(self.health)
|
||||
end
|
||||
|
||||
self.object:set_hp(self.health)
|
||||
-- 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
|
||||
|
||||
update_tag(self)
|
||||
|
||||
-- make children grow quicker
|
||||
if self.child == true then
|
||||
-- if not in creative then take item if it was used
|
||||
if not minetest.is_creative_enabled(clicker:get_player_name()) and consume_food then
|
||||
|
||||
-- deduct 10% of the time to adulthood
|
||||
self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1)
|
||||
local item = clicker:get_wielded_item()
|
||||
|
||||
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
|
||||
if not notake then
|
||||
item:take_item()
|
||||
mob_sound(self, "eat", nil, true)
|
||||
end
|
||||
|
||||
clicker:set_wielded_item(item)
|
||||
else
|
||||
-- make sound when fed so many times
|
||||
mob_sound(self, "random", true)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -25,7 +25,15 @@ local table_remove = table.remove
|
|||
local pairs = pairs
|
||||
|
||||
-- range for mob count
|
||||
local aoc_range = 32
|
||||
local aoc_range = 136
|
||||
|
||||
local mob_cap = {
|
||||
monster = 70,
|
||||
animal =10,
|
||||
ambient =15,
|
||||
water = 5, --currently unused
|
||||
water_ambient = 20, --currently unused
|
||||
}
|
||||
|
||||
--do mobs spawn?
|
||||
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
|
||||
|
@ -153,6 +161,10 @@ local list_of_all_biomes = {
|
|||
-- dimension biome:
|
||||
|
||||
"Nether",
|
||||
"BasaltDelta",
|
||||
"CrimsonForest",
|
||||
"WarpedForest",
|
||||
"SoulsandValley",
|
||||
"End",
|
||||
|
||||
-- Overworld regular:
|
||||
|
@ -162,6 +174,8 @@ local list_of_all_biomes = {
|
|||
"Swampland",
|
||||
"Taiga",
|
||||
"ExtremeHills",
|
||||
"ExtremeHillsM",
|
||||
"ExtremeHills+_snowtop",
|
||||
"Jungle",
|
||||
"Savanna",
|
||||
"BirchForest",
|
||||
|
@ -180,7 +194,6 @@ local list_of_all_biomes = {
|
|||
"ExtremeHills+_snowtop",
|
||||
"MesaPlateauFM_grasstop",
|
||||
"JungleEdgeM",
|
||||
"ExtremeHillsM",
|
||||
"JungleM",
|
||||
"BirchForestM",
|
||||
"MesaPlateauF",
|
||||
|
@ -192,11 +205,26 @@ local list_of_all_biomes = {
|
|||
}
|
||||
|
||||
-- count how many mobs are in an area
|
||||
local function count_mobs(pos)
|
||||
local function count_mobs(pos,r,mob_type)
|
||||
local num = 0
|
||||
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
|
||||
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
|
||||
end
|
||||
end
|
||||
return num
|
||||
|
@ -289,7 +317,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,
|
||||
|
@ -376,11 +404,52 @@ 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 dbg_spawn_attempts = 0
|
||||
local dbg_spawn_succ = 0
|
||||
|
||||
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
|
||||
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 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
|
||||
return o
|
||||
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
|
||||
})
|
||||
|
||||
if mobs_spawn then
|
||||
|
||||
local perlin_noise
|
||||
|
||||
local function spawn_a_mob(pos, dimension, y_min, y_max)
|
||||
dbg_spawn_attempts = dbg_spawn_attempts + 1
|
||||
local dimension = dimension or mcl_worlds.pos_to_dimension(pos)
|
||||
local goal_pos = get_next_mob_spawn_pos(pos)
|
||||
local spawning_position_list = find_nodes_in_area_under_air(
|
||||
|
@ -391,9 +460,6 @@ 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
|
||||
|
@ -407,6 +473,8 @@ if mobs_spawn then
|
|||
|
||||
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_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"})
|
||||
|
@ -426,6 +494,7 @@ if mobs_spawn then
|
|||
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
|
||||
|
@ -438,7 +507,12 @@ if mobs_spawn then
|
|||
end
|
||||
local mob_def = mob_library_worker_table[mob_index]
|
||||
local mob_type = minetest.registered_entities[mob_def.name].type
|
||||
local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4
|
||||
local mob_count_wide = count_mobs(pos,aoc_range,mob_type)
|
||||
local mob_count = count_mobs(spawning_position,32,mob_type)
|
||||
if mob_def
|
||||
and mob_count_wide < (mob_cap[mob_type] or 15)
|
||||
and mob_count < 5
|
||||
and spawning_position.y >= mob_def.min_height
|
||||
and spawning_position.y <= mob_def.max_height
|
||||
and mob_def.dimension == dimension
|
||||
|
@ -446,14 +520,29 @@ if mobs_spawn then
|
|||
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.type_of_spawning ~= "ground" or not is_leaf)
|
||||
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)
|
||||
and (mob_def.type_of_spawning ~= "water" or is_water)
|
||||
and not is_bedrock
|
||||
then
|
||||
if mob_def.type_of_spawning == "water" then
|
||||
spawning_position = get_water_spawn(spawning_position)
|
||||
if not spawning_position then
|
||||
return
|
||||
end
|
||||
end
|
||||
--everything is correct, spawn mob
|
||||
local object = minetest.add_entity(spawning_position, mob_def.name)
|
||||
local object
|
||||
if spawn_in_group then
|
||||
object = spawn_group(spawning_position,mob_def,{gotten_node},spawn_in_group,spawn_in_group_min)
|
||||
else object = minetest.add_entity(spawning_position, mob_def.name)
|
||||
end
|
||||
|
||||
|
||||
if object then
|
||||
return mob_def.on_spawn and mob_def.on_spawn(object, pos)
|
||||
return mob_def.on_spawn and mob_def.on_spawn(object, spawning_position)
|
||||
end
|
||||
end
|
||||
current_summary_chance = current_summary_chance - mob_chance
|
||||
|
|
|
@ -46,6 +46,9 @@ 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)
|
||||
minetest.after(0, wither_spawn, pointed.above)
|
||||
old_on_place(itemstack, placer, pointed)
|
||||
local n = minetest.get_node(vector.offset(pointed.above,0,-1,0))
|
||||
if n and n.name == "mcl_nether:soul_sand" then
|
||||
minetest.after(0, wither_spawn, pointed.above)
|
||||
end
|
||||
return old_on_place(itemstack, placer, pointed)
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ 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,
|
||||
|
|
|
@ -16,6 +16,8 @@ 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,
|
||||
|
|
|
@ -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, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||
if mcl_mobs:protect(self, clicker) then return end
|
||||
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
|
||||
end,
|
||||
|
@ -122,8 +122,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ExtremeHillsM",
|
||||
"ExtremeHills+",
|
||||
"ExtremeHills+_snowtop",
|
||||
"StoneBeach",
|
||||
"Plains",
|
||||
"Plains_beach",
|
||||
"SunflowerPlains",
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
--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_fishing: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)
|
|
@ -48,7 +48,7 @@ local cow_def = {
|
|||
run_end = 40,
|
||||
},
|
||||
on_rightclick = function(self, clicker)
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||
if mcl_mobs:protect(self, clicker) then return end
|
||||
|
||||
if self.child then
|
||||
|
@ -83,9 +83,11 @@ 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, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||
if mcl_mobs:protect(self, clicker) then return end
|
||||
|
||||
if self.child then
|
||||
|
@ -151,17 +153,12 @@ 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",
|
||||
|
|
|
@ -274,7 +274,6 @@ mcl_mobs:spawn_specific(
|
|||
"Plains",
|
||||
"Desert",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -301,7 +300,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
@ -340,7 +338,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest_deep_ocean",
|
||||
"JungleM_deep_ocean",
|
||||
"FlowerForest_deep_ocean",
|
||||
"MushroomIsland_ocean",
|
||||
"MegaTaiga_ocean",
|
||||
"StoneBeach_deep_ocean",
|
||||
"IcePlainsSpikes_deep_ocean",
|
||||
|
@ -350,7 +347,6 @@ mcl_mobs:spawn_specific(
|
|||
"MesaBryce_deep_ocean",
|
||||
"ExtremeHills+_deep_ocean",
|
||||
"ExtremeHills_ocean",
|
||||
"MushroomIsland_deep_ocean",
|
||||
"Forest_ocean",
|
||||
"MegaTaiga_deep_ocean",
|
||||
"JungleEdge_ocean",
|
||||
|
@ -376,7 +372,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
--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)
|
|
@ -35,6 +35,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
|
|||
},
|
||||
physical = true,
|
||||
damage = 10,
|
||||
knock_back = false,
|
||||
jump = true,
|
||||
jump_height = 14,
|
||||
fly = true,
|
||||
|
|
|
@ -627,7 +627,6 @@ mcl_mobs:spawn_specific(
|
|||
"Plains",
|
||||
"Desert",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -654,7 +653,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
@ -693,7 +691,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest_deep_ocean",
|
||||
"JungleM_deep_ocean",
|
||||
"FlowerForest_deep_ocean",
|
||||
"MushroomIsland_ocean",
|
||||
"MegaTaiga_ocean",
|
||||
"StoneBeach_deep_ocean",
|
||||
"IcePlainsSpikes_deep_ocean",
|
||||
|
@ -703,7 +700,6 @@ mcl_mobs:spawn_specific(
|
|||
"MesaBryce_deep_ocean",
|
||||
"ExtremeHills+_deep_ocean",
|
||||
"ExtremeHills_ocean",
|
||||
"MushroomIsland_deep_ocean",
|
||||
"Forest_ocean",
|
||||
"MegaTaiga_deep_ocean",
|
||||
"JungleEdge_ocean",
|
||||
|
@ -729,7 +725,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
@ -766,15 +761,32 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"SoulsandVall3ey",
|
||||
},
|
||||
0,
|
||||
7,
|
||||
11,
|
||||
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)
|
||||
|
|
|
@ -23,6 +23,7 @@ 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"},
|
||||
},
|
||||
|
@ -81,12 +82,14 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"SoulsandValley",
|
||||
"BasaltDelta",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
7,
|
||||
30,
|
||||
18000,
|
||||
72000,
|
||||
2,
|
||||
mcl_vars.mg_nether_min,
|
||||
mcl_vars.mg_nether_max)
|
||||
|
@ -105,7 +108,12 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
|
|||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 6},
|
||||
}, nil)
|
||||
mcl_mobs:boom(self, self.object:get_pos(), 1, true)
|
||||
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
|
||||
end,
|
||||
|
||||
hit_mob = function(self, mob)
|
||||
|
|
|
@ -8,12 +8,14 @@ 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,
|
||||
|
|
|
@ -81,11 +81,27 @@ for b=1, #horse_base do
|
|||
end
|
||||
end
|
||||
|
||||
-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems
|
||||
-- this results in existing horses wearing armor would still have the old texture filename in their
|
||||
-- properties this function updates them. It should be removed some time in the future when we can be
|
||||
-- reasonably sure all horses that want it get the new nexture.
|
||||
local function update_textures(self)
|
||||
local old = "mobs_mc_horse_armor_"
|
||||
local txt = self.object:get_properties().textures
|
||||
if txt[2]:find(old) then
|
||||
txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_")
|
||||
self.object:set_properties({textures=txt})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Horse
|
||||
local horse = {
|
||||
description = S("Horse"),
|
||||
type = "animal",
|
||||
spawn_class = "passive",
|
||||
spawn_in_group_min = 2,
|
||||
spawn_in_group = 6,
|
||||
visual = "mesh",
|
||||
mesh = "mobs_mc_horse.b3d",
|
||||
visual_size = {x=3.0, y=3.0},
|
||||
|
@ -138,7 +154,7 @@ local horse = {
|
|||
max = 2,
|
||||
looting = "common",},
|
||||
},
|
||||
|
||||
on_spawn = update_textures,
|
||||
do_custom = function(self, dtime)
|
||||
|
||||
-- set needed values if not already present
|
||||
|
@ -476,6 +492,8 @@ 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,
|
||||
|
@ -528,41 +546,14 @@ 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",
|
||||
"Jungle",
|
||||
"Jungle_shore",
|
||||
"JungleM",
|
||||
"JungleM_shore",
|
||||
"JungleEdge",
|
||||
"JungleEdgeM",
|
||||
"Swampland",
|
||||
"Swampland_shore"
|
||||
"Savanna_beach",
|
||||
"Plains_beach",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
@ -572,20 +563,22 @@ minetest.LIGHT_MAX+1,
|
|||
mobs_mc.water_level+3,
|
||||
mcl_vars.mg_overworld_max)
|
||||
|
||||
|
||||
mcl_mobs:spawn_specific(
|
||||
"mobs_mc:donkey",
|
||||
"overworld",
|
||||
"ground",
|
||||
{
|
||||
"Mesa",
|
||||
"MesaPlateauFM_grasstop",
|
||||
"MesaPlateauF",
|
||||
"MesaPlateauFM",
|
||||
"MesaPlateauF_grasstop",
|
||||
"MesaBryce",
|
||||
"flat",
|
||||
"Plains",
|
||||
"Plains_beach",
|
||||
"SunflowerPlains",
|
||||
"Savanna",
|
||||
"Savanna_beach",
|
||||
"SavannaM",
|
||||
"Savanna_beach",
|
||||
"Plains_beach",
|
||||
},
|
||||
0,
|
||||
9,
|
||||
minetest.LIGHT_MAX+1,
|
||||
30,
|
||||
15000,
|
||||
|
|
|
@ -142,3 +142,7 @@ 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 .. "/dolphin.lua")
|
||||
|
|
|
@ -37,6 +37,7 @@ 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,
|
||||
|
|
|
@ -28,11 +28,17 @@ 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",
|
||||
|
@ -45,7 +51,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
|
|||
},
|
||||
visual_size = {x=3, y=3},
|
||||
makes_footstep_sound = true,
|
||||
runaway = true,
|
||||
runaway = false,
|
||||
walk_velocity = 1,
|
||||
run_velocity = 4.4,
|
||||
follow_velocity = 4.4,
|
||||
|
@ -211,24 +217,46 @@ 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",
|
||||
{
|
||||
"Mesa",
|
||||
"MesaPlateauFM_grasstop",
|
||||
"MesaPlateauF",
|
||||
"MesaPlateauFM",
|
||||
"MesaPlateauF_grasstop",
|
||||
"MesaBryce",
|
||||
"Jungle",
|
||||
"Jungle_shore",
|
||||
"JungleM",
|
||||
"JungleM_shore",
|
||||
"Savanna",
|
||||
"SavannaM",
|
||||
"SavannaM_beach",
|
||||
"Savanna_beach",
|
||||
"Savanna_ocean",
|
||||
"JungleEdge",
|
||||
"JungleEdgeM",
|
||||
"ExtremeHills",
|
||||
"ExtremeHills_beach",
|
||||
"ExtremeHillsM",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
|
|
@ -1,64 +1,58 @@
|
|||
# textdomain: mobs_mc
|
||||
Agent=Agente
|
||||
Bat=Murciélago
|
||||
Blaze=Blaze
|
||||
Chicken=Pollo
|
||||
Cod=Bacalao
|
||||
Cow=Vaca
|
||||
Mooshroom=Champiñaca
|
||||
Mooshroom=Champivaca
|
||||
Creeper=Creeper
|
||||
Ender Dragon=Enderdragón
|
||||
Dolphin=Delfín
|
||||
Ender Dragon=Ender Dragon
|
||||
Enderman=Enderman
|
||||
Endermite=Endermite
|
||||
Ghast=Ghast
|
||||
Elder Guardian=Gran guardián
|
||||
Guardian=Guardián
|
||||
Horse=Caballo
|
||||
Skeleton Horse=Caballo esquelético
|
||||
Zombie Horse=Caballo zombie
|
||||
Elder Guardian=Guardián Anciano
|
||||
Donkey=Burro
|
||||
Horse=Caballo
|
||||
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
|
||||
Rabbit=Conejo
|
||||
Killer Bunny=Conejo asesino
|
||||
Rabbit=Conejo
|
||||
Salmon=Salmón
|
||||
Sheep=Oveja
|
||||
Shulker=Shulker
|
||||
Silverfish=Lepisma
|
||||
Skeleton=Esqueleto
|
||||
Stray=Esqueleto
|
||||
Wither Skeleton=Esqueleto wither
|
||||
Stray=Esqueleto glacial
|
||||
Wither Skeleton=Esqueleto del Wither
|
||||
Magma Cube=Cubo de Magma
|
||||
Slime=Slime
|
||||
Snow Golem=Golem de nieve
|
||||
Spider=Araña
|
||||
Cave Spider=Araña de las cuevas
|
||||
Spider=Araña
|
||||
Squid=Calamar
|
||||
Vex=Ánima
|
||||
Master=Maestro
|
||||
Villager=Aldeano
|
||||
Evoker=Invocador
|
||||
Illusioner=Illusionista
|
||||
Villager=Aldeano
|
||||
Vindicator=Vindicador
|
||||
Zombie Villager=Aldeano zombie
|
||||
Zombie Villager=Aldeano zombi
|
||||
Witch=Bruja
|
||||
Wither=Wither
|
||||
Wolf=Lobo
|
||||
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
|
||||
Baby Husk=Bebé Zombi Momificado
|
||||
Baby Zombie=Bebé Zombi
|
||||
Husk=Zombi Momificado
|
||||
Zombie=Zombi
|
||||
Baby Zombie Pigman=Bebé Hombrecerdo Zombi
|
||||
Zombie Pigman=Hombrecerdo Zombi
|
||||
|
|
|
@ -62,3 +62,6 @@ Weapon Smith=
|
|||
Tool Smith=
|
||||
Cleric=
|
||||
Nitwit=
|
||||
Cod=
|
||||
Salmon=
|
||||
Dolphin=
|
||||
|
|
|
@ -30,6 +30,8 @@ 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,
|
||||
|
|
|
@ -8,8 +8,113 @@ local S = minetest.get_translator("mobs_mc")
|
|||
--###################
|
||||
--################### PARROT
|
||||
--###################
|
||||
local shoulders = {
|
||||
left = vector.new(-3.75,10.5,0),
|
||||
right = vector.new(3.75,10.5,0)
|
||||
}
|
||||
|
||||
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 then
|
||||
return e.sounds[math.random(#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"
|
||||
for _,o in pairs(player:get_children()) do
|
||||
local l = o:get_luaentity()
|
||||
if l and l.name == "mobs_mc:parrot" then
|
||||
local _,_,a = l.object:get_attach()
|
||||
for _,s in pairs(shoulders) do
|
||||
if a and vector.equals(a,s) then
|
||||
if sh == "left" then
|
||||
sh = "right"
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return shoulders[sh]
|
||||
end
|
||||
|
||||
local function perch(self,player)
|
||||
if self.tamed and player:get_player_name() == self.owner and not self.object:get_attach() then
|
||||
local shoulder = get_shoulder(player)
|
||||
if not shoulder then return true end
|
||||
self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true)
|
||||
mcl_mobs:set_animation(self, "stand")
|
||||
end
|
||||
end
|
||||
|
||||
local function check_perch(self,dtime)
|
||||
if self.object:get_attach() then
|
||||
for _,p in pairs(minetest.get_connected_players()) do
|
||||
for _,o in pairs(p:get_children()) do
|
||||
local l = o:get_luaentity()
|
||||
if l and l.name == "mobs_mc:parrot" then
|
||||
local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name
|
||||
local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name
|
||||
local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name
|
||||
if n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0 then
|
||||
o:set_detach()
|
||||
self.detach_timer = 0
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif not self.detach_timer then
|
||||
for _,p in pairs(minetest.get_connected_players()) do
|
||||
if vector.distance(self.object:get_pos(),p:get_pos()) < 0.5 then
|
||||
perch(self,p)
|
||||
return
|
||||
end
|
||||
end
|
||||
elseif self.detach_timer then
|
||||
if self.detach_timer > 1 then
|
||||
self.detach_timer = nil
|
||||
else
|
||||
self.detach_timer = self.detach_timer + dtime
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:parrot", {
|
||||
description = S("Parrot"),
|
||||
|
@ -45,12 +150,12 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
|
|||
stand_speed = 50,
|
||||
walk_speed = 50,
|
||||
fly_speed = 50,
|
||||
stand_start = 30,
|
||||
stand_end = 45,
|
||||
stand_start = 0,
|
||||
stand_end = 0,
|
||||
fly_start = 30,
|
||||
fly_end = 45,
|
||||
walk_start = 30,
|
||||
walk_end = 45,
|
||||
walk_start = 0,
|
||||
walk_end = 20,
|
||||
-- TODO: actual walk animation
|
||||
--walk_start = 0,
|
||||
--walk_end = 20,
|
||||
|
@ -87,13 +192,19 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
|
|||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Feed to tame, but not breed
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, false, 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
|
||||
perch(self,clicker)
|
||||
end,
|
||||
do_custom = function(self,dtime)
|
||||
check_perch(self,dtime)
|
||||
check_mobimitate(self,dtime)
|
||||
end,
|
||||
do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later....
|
||||
if self.object:get_attach() == puncher then
|
||||
return false --return false explicitly here. mcl_mobs checks for that
|
||||
end
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
|
||||
|
|
|
@ -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, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||
end
|
||||
if mcl_mobs:protect(self, clicker) then return end
|
||||
|
||||
|
@ -194,17 +194,12 @@ 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",
|
||||
|
|
|
@ -76,7 +76,6 @@ mcl_mobs:spawn_specific(
|
|||
"ColdTaiga",
|
||||
"IcePlainsSpikes",
|
||||
"IcePlains",
|
||||
"ExtremeHills+_snowtop",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
|
|
@ -6,9 +6,10 @@ 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,
|
||||
|
@ -74,7 +75,7 @@ local rabbit = {
|
|||
},
|
||||
on_rightclick = function(self, clicker)
|
||||
-- Feed, tame protect or capture
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||
if mcl_mobs:protect(self, clicker) then return end
|
||||
if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end
|
||||
end,
|
||||
|
@ -132,18 +133,9 @@ 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,
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
--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_fishing: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)
|
|
@ -70,6 +70,8 @@ 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,
|
||||
|
@ -195,7 +197,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, true) then return end
|
||||
if mcl_mobs:feed_tame(self, clicker, 1, true, false) 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
|
||||
|
@ -346,7 +348,7 @@ mcl_mobs:spawn_specific(
|
|||
"Swampland",
|
||||
"Swampland_shore"
|
||||
},
|
||||
0,
|
||||
9,
|
||||
minetest.LIGHT_MAX+1,
|
||||
30,
|
||||
15000,
|
||||
|
|
|
@ -33,6 +33,7 @@ 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",
|
||||
|
|
|
@ -162,7 +162,6 @@ mcl_mobs:spawn_specific(
|
|||
"Plains",
|
||||
"Desert",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -189,7 +188,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
@ -228,7 +226,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest_deep_ocean",
|
||||
"JungleM_deep_ocean",
|
||||
"FlowerForest_deep_ocean",
|
||||
"MushroomIsland_ocean",
|
||||
"MegaTaiga_ocean",
|
||||
"StoneBeach_deep_ocean",
|
||||
"IcePlainsSpikes_deep_ocean",
|
||||
|
@ -238,7 +235,6 @@ mcl_mobs:spawn_specific(
|
|||
"MesaBryce_deep_ocean",
|
||||
"ExtremeHills+_deep_ocean",
|
||||
"ExtremeHills_ocean",
|
||||
"MushroomIsland_deep_ocean",
|
||||
"Forest_ocean",
|
||||
"MegaTaiga_deep_ocean",
|
||||
"JungleEdge_ocean",
|
||||
|
@ -264,7 +260,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
@ -302,10 +297,10 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"SoulsandValley",
|
||||
},
|
||||
0,
|
||||
7,
|
||||
minetest.LIGHT_MAX+1,
|
||||
30,
|
||||
10000,
|
||||
3,
|
||||
|
|
|
@ -101,7 +101,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"SoulsandValley",
|
||||
},
|
||||
0,
|
||||
7,
|
||||
|
|
|
@ -402,7 +402,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"BasaltDelta",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
@ -418,7 +419,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"BasaltDelta",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
@ -433,7 +435,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"BasaltDelta",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
@ -443,11 +446,6 @@ 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")
|
||||
|
|
|
@ -109,7 +109,6 @@ mcl_mobs:spawn_specific(
|
|||
"Plains",
|
||||
"Desert",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -136,7 +135,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
@ -175,7 +173,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest_deep_ocean",
|
||||
"JungleM_deep_ocean",
|
||||
"FlowerForest_deep_ocean",
|
||||
"MushroomIsland_ocean",
|
||||
"MegaTaiga_ocean",
|
||||
"StoneBeach_deep_ocean",
|
||||
"IcePlainsSpikes_deep_ocean",
|
||||
|
@ -185,7 +182,6 @@ mcl_mobs:spawn_specific(
|
|||
"MesaBryce_deep_ocean",
|
||||
"ExtremeHills+_deep_ocean",
|
||||
"ExtremeHills_ocean",
|
||||
"MushroomIsland_deep_ocean",
|
||||
"Forest_ocean",
|
||||
"MegaTaiga_deep_ocean",
|
||||
"JungleEdge_ocean",
|
||||
|
@ -211,7 +207,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
|
After Width: | Height: | Size: 766 B |
After Width: | Height: | Size: 443 B |
After Width: | Height: | Size: 830 B |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 385 B |
After Width: | Height: | Size: 307 B |
|
@ -136,8 +136,7 @@ local professions = {
|
|||
{
|
||||
{ { "mcl_fishing:fish_raw", 6, 15,}, E1 },
|
||||
{ { "mcl_fishing:salmon_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:salmon_cooked", 6, 6 } },
|
||||
-- FIXME missing campfire
|
||||
-- {{ "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire",1,1} },
|
||||
{ { "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire_lit",1,1} },
|
||||
},
|
||||
{
|
||||
{ { "mcl_fishing:salmon_raw", 6, 13,}, E1 },
|
||||
|
@ -427,7 +426,7 @@ local professions = {
|
|||
"mobs_mc_villager_weaponsmith.png",
|
||||
"mobs_mc_villager_weaponsmith.png",
|
||||
},
|
||||
jobsite = "mcl_furnaces:furnace", --FIXME: grindstone
|
||||
jobsite = "mcl_grindstone:grindstone",
|
||||
trades = {
|
||||
{
|
||||
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||
|
@ -458,7 +457,7 @@ local professions = {
|
|||
"mobs_mc_villager_toolsmith.png",
|
||||
"mobs_mc_villager_toolsmith.png",
|
||||
},
|
||||
jobsite = "mcl_anvils:anvil", --FIXME: smithing table
|
||||
jobsite = "mcl_smithing_table:table",
|
||||
trades = {
|
||||
{
|
||||
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||
|
@ -613,6 +612,8 @@ local function employ(self,jobsite_pos)
|
|||
end
|
||||
|
||||
local function look_for_job(self)
|
||||
if self.last_jobhunt and os.time() - self.last_jobhunt < 360 then return end
|
||||
self.last_jobhunt = os.time() + math.random(0,60)
|
||||
local p = self.object:get_pos()
|
||||
local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48),jobsites)
|
||||
for _,n in pairs(nn) do
|
||||
|
@ -628,14 +629,24 @@ local function look_for_job(self)
|
|||
end
|
||||
|
||||
local function get_a_job(self)
|
||||
if self.child then return end
|
||||
local p = self.object:get_pos()
|
||||
local nn = minetest.find_nodes_in_area(vector.offset(p,-8,-8,-8),vector.offset(p,8,8,8),jobsites)
|
||||
for _,n in pairs(nn) do
|
||||
if n and employ(self,n) then return true end
|
||||
end
|
||||
local n = minetest.find_node_near(p,1,jobsites)
|
||||
if n and employ(self,n) then return true end
|
||||
if self.state ~= "gowp" then look_for_job(self) end
|
||||
end
|
||||
|
||||
local function check_jobsite(self)
|
||||
if self._traded or not self._jobsite then return end
|
||||
local n = mcl_vars.get_node(self._jobsite)
|
||||
local m = minetest.get_meta(self._jobsite)
|
||||
if m:get_string("villager") ~= self._id then
|
||||
self._profession = "unemployed"
|
||||
self._trades = nil
|
||||
set_textures(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function update_max_tradenum(self)
|
||||
if not self._trades then
|
||||
return
|
||||
|
@ -724,7 +735,10 @@ local function set_trade(trader, player, inv, concrete_tradenum)
|
|||
local trade = trades[concrete_tradenum]
|
||||
inv:set_stack("wanted", 1, ItemStack(trade.wanted[1]))
|
||||
local offered = ItemStack(trade.offered)
|
||||
mcl_enchanting.load_enchantments(offered)
|
||||
-- Only load enchantments for enchanted items; fixes unnecessary metadata being applied to regular items from villagers.
|
||||
if mcl_enchanting.is_enchanted(offered:get_name()) then
|
||||
mcl_enchanting.load_enchantments(offered)
|
||||
end
|
||||
inv:set_stack("offered", 1, offered)
|
||||
if trade.wanted[2] then
|
||||
local wanted2 = ItemStack(trade.wanted[2])
|
||||
|
@ -982,6 +996,11 @@ local trade_inventory = {
|
|||
elseif listname == "output" then
|
||||
if not trader_exists(player:get_player_name()) then
|
||||
return 0
|
||||
-- Begin Award Code
|
||||
-- May need to be moved if award gets unlocked in the wrong cases.
|
||||
elseif trader_exists(player:get_player_name()) then
|
||||
awards.unlock(player:get_player_name(), "mcl:whatAdeal")
|
||||
-- End Award Code
|
||||
end
|
||||
-- Only allow taking full stack
|
||||
local count = stack:get_count()
|
||||
|
@ -1094,6 +1113,7 @@ local trade_inventory = {
|
|||
local trader = player_trading_with[name]
|
||||
local tradenum = player_tradenum[name]
|
||||
local trades
|
||||
trader._traded = true
|
||||
if trader and trader._trades then
|
||||
trades = minetest.deserialize(trader._trades)
|
||||
end
|
||||
|
@ -1224,6 +1244,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
-- TODO: sounds
|
||||
sounds = {
|
||||
random = "mobs_mc_villager",
|
||||
damage = "mobs_mc_villager_hurt",
|
||||
distance = 10,
|
||||
},
|
||||
animation = {
|
||||
|
@ -1236,10 +1257,12 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
run_speed = 25,
|
||||
run_start = 0,
|
||||
run_end = 40,
|
||||
die_speed = 15,
|
||||
die_start = 210,
|
||||
die_end = 220,
|
||||
die_loop = false,
|
||||
head_shake_start = 210,
|
||||
head_shake_end = 220,
|
||||
head_shake_loop = false,
|
||||
head_nod_start = 210,
|
||||
head_nod_end = 220,
|
||||
head_nod_loop = false,
|
||||
},
|
||||
follow = pick_up,
|
||||
nofollow = true,
|
||||
|
@ -1261,13 +1284,12 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
end
|
||||
end
|
||||
if clicker then
|
||||
mcl_mobs:feed_tame(self, clicker, 1, true, false)
|
||||
mcl_mobs:feed_tame(self, clicker, 1, true, false, true)
|
||||
return
|
||||
end
|
||||
return true --do not pick up
|
||||
end,
|
||||
on_rightclick = function(self, clicker)
|
||||
local trg=vector.new(0,9,0)
|
||||
if self._jobsite then
|
||||
mcl_mobs:gopath(self,self._jobsite,function()
|
||||
--minetest.log("arrived at jobsite")
|
||||
|
@ -1344,20 +1366,24 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
end
|
||||
if self._profession == "unemployed" then
|
||||
get_a_job(self)
|
||||
else
|
||||
check_jobsite(self)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_spawn = function(self)
|
||||
if not self._profession then
|
||||
self._profession = "unemployed"
|
||||
if math.random(100) == 1 then
|
||||
self._profession = "nitwit"
|
||||
end
|
||||
end
|
||||
if self._id then
|
||||
set_textures(self)
|
||||
return
|
||||
end
|
||||
self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random()))
|
||||
self._profession = "unemployed"
|
||||
if math.random(100) == 1 then
|
||||
self._profession = "nitwit"
|
||||
end
|
||||
set_textures(self)
|
||||
end,
|
||||
on_die = function(self, pos)
|
||||
|
@ -1376,7 +1402,8 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
})
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
Villager spawning in mcl_villages
|
||||
mcl_mobs:spawn_specific(
|
||||
"mobs_mc:villager",
|
||||
"overworld",
|
||||
|
@ -1406,6 +1433,6 @@ minetest.LIGHT_MAX+1,
|
|||
4,
|
||||
mobs_mc.water_level+1,
|
||||
mcl_vars.mg_overworld_max)
|
||||
|
||||
--]]
|
||||
-- spawn eggs
|
||||
mcl_mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0)
|
||||
|
|
|
@ -29,6 +29,7 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", {
|
|||
description = S("Zombie Villager"),
|
||||
type = "monster",
|
||||
spawn_class = "hostile",
|
||||
spawn_in_group = 1,
|
||||
hp_min = 20,
|
||||
hp_max = 20,
|
||||
xp_min = 5,
|
||||
|
@ -119,20 +120,7 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", {
|
|||
villager_obj:set_yaw(yaw)
|
||||
villager.target_yaw = yaw
|
||||
villager.nametag = self.nametag
|
||||
local texture = self.base_texture[1]:gsub("zombie", "villager")
|
||||
if texture == "mobs_mc_villager_villager.png" then
|
||||
texture = "mobs_mc_villager.png"
|
||||
end
|
||||
local textures = {texture}
|
||||
villager.base_texture = textures
|
||||
villager_obj:set_properties({textures = textures})
|
||||
local matches = {}
|
||||
for prof, tex in pairs(professions) do
|
||||
if texture == tex then
|
||||
table.insert(matches, prof)
|
||||
end
|
||||
end
|
||||
villager._profession = matches[math.random(#matches)]
|
||||
villager._profession = "unemployed"
|
||||
self._curing = nil
|
||||
mcl_burning.extinguish(obj)
|
||||
obj:remove()
|
||||
|
@ -160,7 +148,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
@ -197,7 +184,6 @@ mcl_mobs:spawn_specific(
|
|||
"Plains",
|
||||
"Desert",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -224,7 +210,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
|
|
@ -18,6 +18,7 @@ local wolf = {
|
|||
xp_max = 3,
|
||||
passive = false,
|
||||
group_attack = true,
|
||||
spawn_in_group = 8,
|
||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
|
||||
visual = "mesh",
|
||||
mesh = "mobs_mc_wolf.b3d",
|
||||
|
@ -232,29 +233,22 @@ dog.on_rightclick = function(self, clicker)
|
|||
end
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:dog", dog)
|
||||
|
||||
-- Spawn
|
||||
mcl_mobs:spawn_specific(
|
||||
"mobs_mc:wolf",
|
||||
"overworld",
|
||||
"ground",
|
||||
{
|
||||
"FlowerForest",
|
||||
"Swampland",
|
||||
"Taiga",
|
||||
"ExtremeHills",
|
||||
"BirchForest",
|
||||
"MegaSpruceTaiga",
|
||||
"MegaTaiga",
|
||||
"ExtremeHills+",
|
||||
"Forest",
|
||||
"Plains",
|
||||
"ColdTaiga",
|
||||
"SunflowerPlains",
|
||||
"RoofedForest",
|
||||
"MesaPlateauFM_grasstop",
|
||||
"ExtremeHillsM",
|
||||
"BirchForestM",
|
||||
"Taiga",
|
||||
"MegaSpruceTaiga",
|
||||
"MegaTaiga",
|
||||
"Forest",
|
||||
"ColdTaiga",
|
||||
"FlowerForest_beach",
|
||||
"Forest_beach",
|
||||
"ColdTaiga_beach_water",
|
||||
"Taiga_beach",
|
||||
"ColdTaiga_beach",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
|
|
@ -162,7 +162,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
@ -198,7 +197,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest",
|
||||
"Plains",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -225,7 +223,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
@ -254,7 +251,6 @@ mcl_mobs:spawn_specific(
|
|||
"RoofedForest_underground",
|
||||
"Jungle_underground",
|
||||
"Swampland_underground",
|
||||
"MushroomIsland_underground",
|
||||
"BirchForest_underground",
|
||||
"Plains_underground",
|
||||
"MesaPlateauF_underground",
|
||||
|
@ -290,7 +286,6 @@ mcl_mobs:spawn_specific(
|
|||
"Forest",
|
||||
"Plains",
|
||||
"ColdTaiga",
|
||||
"MushroomIsland",
|
||||
"IcePlainsSpikes",
|
||||
"SunflowerPlains",
|
||||
"IcePlains",
|
||||
|
@ -317,7 +312,6 @@ mcl_mobs:spawn_specific(
|
|||
"ExtremeHills_beach",
|
||||
"ColdTaiga_beach",
|
||||
"Swampland_shore",
|
||||
"MushroomIslandShore",
|
||||
"JungleM_shore",
|
||||
"Jungle_shore",
|
||||
"MesaPlateauFM_sandlevel",
|
||||
|
|
|
@ -118,7 +118,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"CrimsonForest",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
@ -133,7 +134,8 @@ mcl_mobs:spawn_specific(
|
|||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
"Nether",
|
||||
"CrimsonForest",
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
|
|
|
@ -238,8 +238,8 @@ after(5, function(dtime)
|
|||
end)
|
||||
|
||||
minetest.register_chatcommand("lightning", {
|
||||
params = "[<X> <Y> <Z>]",
|
||||
description = S("Let lightning strike at the specified position or yourself"),
|
||||
params = "[<X> <Y> <Z> | <player name>]",
|
||||
description = S("Let lightning strike at the specified position or player. No parameter will strike yourself."),
|
||||
privs = { maphack = true },
|
||||
func = function(name, param)
|
||||
local pos = {}
|
||||
|
@ -247,21 +247,21 @@ minetest.register_chatcommand("lightning", {
|
|||
pos.x = tonumber(pos.x)
|
||||
pos.y = tonumber(pos.y)
|
||||
pos.z = tonumber(pos.z)
|
||||
local player_to_strike
|
||||
if not (pos.x and pos.y and pos.z) then
|
||||
pos = nil
|
||||
player_to_strike = minetest.get_player_by_name(param)
|
||||
if not player_to_strike and param == "" then
|
||||
player_to_strike = minetest.get_player_by_name(name)
|
||||
end
|
||||
end
|
||||
if name == "" and pos == nil then
|
||||
if not player_to_strike and pos == nil then
|
||||
return false, "No position specified and unknown player"
|
||||
end
|
||||
if pos then
|
||||
lightning.strike(pos)
|
||||
else
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
lightning.strike(player:get_pos())
|
||||
else
|
||||
return false, S("No position specified and unknown player")
|
||||
end
|
||||
elseif player_to_strike then
|
||||
lightning.strike(player_to_strike:get_pos())
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# textdomain: lightning
|
||||
@1 was struck by lightning.=
|
||||
Let lightning strike at the specified position or yourself=
|
||||
Let lightning strike at the specified position or player. No parameter will strike yourself.=
|
||||
No position specified and unknown player=
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
mcl_weather.nether_dust = {}
|
||||
mcl_weather.nether_dust.particlespawners = {}
|
||||
|
||||
local PARTICLES_COUNT_NETHER_DUST = tonumber(minetest.settings:get("mcl_weather_dust_particles")) or 150
|
||||
|
||||
local psdef= {
|
||||
amount = 150,
|
||||
amount = PARTICLES_COUNT_NETHER_DUST,
|
||||
time = 0,
|
||||
minpos = vector.new(-15,-15,-15),
|
||||
maxpos =vector.new(15,15,15),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local PARTICLES_COUNT_RAIN = 100
|
||||
local PARTICLES_COUNT_THUNDER = 300
|
||||
local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_particles")) or 500
|
||||
local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900
|
||||
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
|
@ -20,44 +20,26 @@ mcl_weather.rain = {
|
|||
init_done = false,
|
||||
}
|
||||
local update_sound={}
|
||||
local vel=math.random(0,3)
|
||||
local falling_speed=math.random(10,15)
|
||||
local size = math.random(1,3)
|
||||
|
||||
local psdef= {
|
||||
amount = mcl_weather.rain.particles_count,
|
||||
time=0,
|
||||
minpos = vector.new(-6,3,-6),
|
||||
maxpos = vector.new(6,15,6),
|
||||
minvel = vector.new(-vel,-falling_speed,-vel),
|
||||
maxvel = vector.new(vel,-falling_speed+vel,vel),
|
||||
minpos = vector.new(-15,20,-15),
|
||||
maxpos = vector.new(15,25,15),
|
||||
minvel = vector.new(-2,-17,-2),
|
||||
maxvel = vector.new(2,-8,2),
|
||||
minacc = vector.new(0,0,0),
|
||||
maxacc = vector.new(0,-0.4,0),
|
||||
minexptime = 0.5,
|
||||
maxexptime = 2,
|
||||
minsize = size,
|
||||
maxsize= size*2,
|
||||
maxacc = vector.new(0,-0.5,0),
|
||||
minexptime = 1,
|
||||
maxexptime = 4,
|
||||
minsize = 4,
|
||||
maxsize= 8,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
vertical = true,
|
||||
}
|
||||
local psdef_backsplash= {
|
||||
amount = 10,
|
||||
time=0,
|
||||
minpos = vector.new(-3,-1,-3),
|
||||
maxpos = vector.new(3,0,3),
|
||||
minvel = vector.new(-vel,falling_speed*2,-vel),
|
||||
maxvel = vector.new(vel,falling_speed*2+vel,vel),
|
||||
minacc = vector.new(0,0,0),
|
||||
maxacc = vector.new(0,0,0),
|
||||
minexptime = 0.1,
|
||||
maxexptime = 0.2,
|
||||
minsize = size*0.1,
|
||||
maxsize= size*0.5,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
vertical = true,
|
||||
}
|
||||
local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png", "weather_pack_rain_raindrop_1.png"}
|
||||
|
||||
local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png"}
|
||||
|
||||
function mcl_weather.rain.sound_handler(player)
|
||||
return minetest.sound_play("weather_rain", {
|
||||
|
@ -86,12 +68,11 @@ end
|
|||
-- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net.
|
||||
function mcl_weather.rain.add_rain_particles(player)
|
||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count
|
||||
local l = false
|
||||
for k,v in pairs(textures) do
|
||||
psdef.texture=v
|
||||
mcl_weather.add_spawner_player(player,"rain"..k,psdef)
|
||||
l = l or mcl_weather.add_spawner_player(player,"rain"..k,psdef)
|
||||
end
|
||||
psdef_backsplash.texture=textures[math.random(1,#textures)]
|
||||
local l=mcl_weather.add_spawner_player(player,"rainbacksplash",psdef_backsplash)
|
||||
if l then
|
||||
update_sound[player:get_player_name()]=true
|
||||
end
|
||||
|
@ -185,14 +166,14 @@ function mcl_weather.rain.make_weather()
|
|||
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
local pos=player:get_pos()
|
||||
if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(pos) or not mcl_weather.is_outdoor(pos) then
|
||||
if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(pos) then
|
||||
mcl_weather.rain.remove_sound(player)
|
||||
mcl_weather.remove_spawners_player(player)
|
||||
return false
|
||||
else
|
||||
mcl_weather.rain.add_player(player)
|
||||
mcl_weather.rain.add_rain_particles(player)
|
||||
mcl_weather.rain.update_sound(player)
|
||||
end
|
||||
mcl_weather.rain.add_player(player)
|
||||
mcl_weather.rain.add_rain_particles(player)
|
||||
mcl_weather.rain.update_sound(player)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -200,11 +181,9 @@ end
|
|||
function mcl_weather.rain.set_particles_mode(mode)
|
||||
if mode == "thunder" then
|
||||
psdef.amount=PARTICLES_COUNT_THUNDER
|
||||
psdef_backsplash.amount=PARTICLES_COUNT_THUNDER
|
||||
mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER
|
||||
else
|
||||
psdef.amount=PARTICLES_COUNT_RAIN
|
||||
psdef_backsplash.amount=PARTICLES_COUNT_RAIN
|
||||
mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN
|
||||
end
|
||||
end
|
||||
|
|
|
@ -146,8 +146,25 @@ mcl_weather.skycolor = {
|
|||
player:set_stars({visible = false})
|
||||
mcl_weather.skycolor.override_day_night_ratio(player, 0.5)
|
||||
elseif dim == "nether" then
|
||||
player:set_sky({ type = "plain",
|
||||
base_color = "#300808",
|
||||
local nether_sky = {
|
||||
Nether = "#300808",
|
||||
BasaltDelta = "#685F70",
|
||||
SoulsandValley = "#1B4745",
|
||||
CrimsonForest = "#330303",
|
||||
WarpedForest = "#1A051A"
|
||||
}
|
||||
local biometint = nether_sky[minetest.get_biome_name(minetest.get_biome_data(player:get_pos()).biome)]
|
||||
|
||||
player:set_sky({
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky = "#300808",
|
||||
day_horizon = biometint,
|
||||
dawn_sky = "#300808",
|
||||
dawn_horizon = biometint,
|
||||
night_sky = "#300808",
|
||||
night_horizon = biometint,
|
||||
},
|
||||
clouds = false,
|
||||
})
|
||||
player:set_sun({visible = false , sunrise_visible = false})
|
||||
|
|
|
@ -2,21 +2,21 @@ local get_connected_players = minetest.get_connected_players
|
|||
|
||||
mcl_weather.snow = {}
|
||||
|
||||
mcl_weather.snow.particles_count = 15
|
||||
local PARTICLES_COUNT_SNOW = tonumber(minetest.settings:get("mcl_weather_snow_particles")) or 100
|
||||
mcl_weather.snow.init_done = false
|
||||
|
||||
local psdef= {
|
||||
amount = 99,
|
||||
amount = PARTICLES_COUNT_SNOW,
|
||||
time = 0, --stay on til we turn it off
|
||||
minpos = vector.new(-15,-5,-15),
|
||||
maxpos =vector.new(15,10,15),
|
||||
minvel = vector.new(0,-1,0),
|
||||
maxvel = vector.new(0,-4,0),
|
||||
minpos = vector.new(-25,20,-25),
|
||||
maxpos =vector.new(25,25,25),
|
||||
minvel = vector.new(-0.2,-1,-0.2),
|
||||
maxvel = vector.new(0.2,-4,0.2),
|
||||
minacc = vector.new(0,-1,0),
|
||||
maxacc = vector.new(0,-4,0),
|
||||
minexptime = 1,
|
||||
maxexptime = 1,
|
||||
minsize = 0.5,
|
||||
minexptime = 3,
|
||||
maxexptime = 5,
|
||||
minsize = 2,
|
||||
maxsize = 5,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
|
@ -70,13 +70,13 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) or not mcl_weather.is_outdoor(player:get_pos())) then
|
||||
if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) then
|
||||
mcl_weather.remove_spawners_player(player)
|
||||
return false
|
||||
end
|
||||
for i=1,2 do
|
||||
psdef.texture="weather_pack_snow_snowflake"..i..".png"
|
||||
mcl_weather.add_spawner_player(player,"snow"..i,psdef)
|
||||
else
|
||||
for i=1,2 do
|
||||
psdef.texture="weather_pack_snow_snowflake"..i..".png"
|
||||
mcl_weather.add_spawner_player(player,"snow"..i,psdef)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -101,6 +101,17 @@ awards.register_achievement("mcl:bookcase", {
|
|||
}
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:buildIronPickaxe", {
|
||||
title = S("Isn't It Iron Pick"),
|
||||
description = S("Craft a iron pickaxe using sticks and iron."),
|
||||
icon = "default_tool_steelpick.png",
|
||||
trigger = {
|
||||
type = "craft",
|
||||
item = "mcl_tools:pick_iron",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- Item pickup achievements: These are awarded when picking up a certain item.
|
||||
-- The achivements are manually given in the mod mcl_item_entity.
|
||||
awards.register_achievement("mcl:diamonds", {
|
||||
|
@ -125,6 +136,18 @@ awards.register_achievement("mcl:mineWood", {
|
|||
icon = "default_tree.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:whosCuttingOnions", {
|
||||
title = S("Who is Cutting Onions?"),
|
||||
description = S("Pick up a crying obsidian from the floor."),
|
||||
icon = "default_obsidian.png^mcl_core_crying_obsidian.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:hiddenInTheDepths", {
|
||||
title = S("Hidden in the Depths"),
|
||||
description = S("Pick up an Ancient Debris from the floor."),
|
||||
icon = "mcl_nether_ancient_debris_side.png",
|
||||
})
|
||||
|
||||
-- Smelting achivements: These are awarded when picking up an item from a furnace
|
||||
-- output. They are given in mcl_furnaces.
|
||||
awards.register_achievement("mcl:acquireIron", {
|
||||
|
@ -158,9 +181,89 @@ awards.register_achievement("mcl:snipeSkeleton", {
|
|||
|
||||
-- Triggered in mcl_portals
|
||||
awards.register_achievement("mcl:buildNetherPortal", {
|
||||
title = S("Into the Nether"),
|
||||
title = S("We Need to Go Deeper"),
|
||||
description = S("Use obsidian and a fire starter to construct a Nether portal."),
|
||||
icon = "default_obsidian.png",
|
||||
icon = "mcl_fire_flint_and_steel.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:enterEndPortal", {
|
||||
title = S("The End?"),
|
||||
description = S("Or the beginning?\nHint: Enter an end portal."),
|
||||
icon = "mcl_end_end_stone.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:theNether", {
|
||||
title = S("The Nether"),
|
||||
description = S("Bring summer clothes.\nHint: Enter the Nether."),
|
||||
icon = "mcl_nether_netherrack.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_totems
|
||||
awards.register_achievement("mcl:postMortal", {
|
||||
title = S("Postmortal"),
|
||||
description = S("Use a Totem of Undying to cheat death."),
|
||||
icon = "mcl_totems_totem.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_beds
|
||||
awards.register_achievement("mcl:sweetDreams", {
|
||||
title = S("Sweet Dreams"),
|
||||
description = S("Sleep in a bed to change your respawn point."),
|
||||
icon = "mcl_beds_bed_red.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:notQuiteNineLives", {
|
||||
title = S('Not Quite "Nine" Lives'),
|
||||
description = S("Charge a Respawn Anchor to the maximum."),
|
||||
icon = "respawn_anchor_side4.png",
|
||||
})
|
||||
|
||||
-- Triggered in mobs_mc
|
||||
awards.register_achievement("mcl:whatAdeal", {
|
||||
title = S("What A Deal!"),
|
||||
description = S("Successfully trade with a Villager."),
|
||||
icon = "mcl_core_emerald.png",
|
||||
})
|
||||
|
||||
awards.register_achievement("mcl:tacticalFishing", {
|
||||
title = S("Tactical Fishing"),
|
||||
description = S("Catch a fish... without a fishing rod!"),
|
||||
icon = "pufferfish_bucket.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_fishing
|
||||
awards.register_achievement("mcl:fishyBusiness", {
|
||||
title = S("Fishy Business"),
|
||||
description = S("Catch a fish.\nHint: Catch a fish, salmon, clownfish, or pufferfish."),
|
||||
icon = "mcl_fishing_fishing_rod.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_compass
|
||||
awards.register_achievement("mcl:countryLode", {
|
||||
title = S("Country Lode,\nTake Me Home"),
|
||||
description = S("Use a compass on a Lodestone."),
|
||||
icon = "lodestone_side4.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_smithing_table
|
||||
awards.register_achievement("mcl:seriousDedication", {
|
||||
title = S("Serious Dedication"),
|
||||
description = S("Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices."),
|
||||
icon = "farming_tool_netheritehoe.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_brewing
|
||||
awards.register_achievement("mcl:localBrewery", {
|
||||
title = S("Local Brewery"),
|
||||
description = S("Brew a Potion.\nHint: Take a potion or glass bottle out of the brewing stand."),
|
||||
icon = "mcl_potions_potion_overlay.png^[colorize:#F82423:"..tostring(127).."^mcl_potions_potion_bottle.png",
|
||||
})
|
||||
|
||||
-- Triggered in mcl_enchanting
|
||||
awards.register_achievement("mcl:enchanter", {
|
||||
title = S("Enchanter"),
|
||||
description = S("Enchant an item using an Enchantment Table."),
|
||||
icon = "mcl_enchanting_book_enchanted.png",
|
||||
})
|
||||
|
||||
-- NON-PC ACHIEVEMENTS (XBox, Pocket Edition, etc.)
|
||||
|
|
|
@ -19,7 +19,7 @@ Getting an Upgrade=
|
|||
Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=
|
||||
Hot Topic=
|
||||
Into Fire=
|
||||
Into the Nether=
|
||||
We Need to Go Deeper=
|
||||
Iron Belly=
|
||||
Librarian=
|
||||
Mine emerald ore.=
|
||||
|
@ -47,3 +47,29 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=
|
|||
Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=
|
||||
Use obsidian and a fire starter to construct a Nether portal.=
|
||||
Use wheat to craft a bread.=
|
||||
Who is Cutting Onions?=
|
||||
Pick up a crying obsidian from the floor.=
|
||||
Hidden in the Depths=
|
||||
Pick up an Ancient Debris from the floor.=
|
||||
The Nether=
|
||||
Bring summer clothes.@nHint: Enter the Nether.=
|
||||
Isn't It Iron Pick=
|
||||
Craft a iron pickaxe using sticks and iron.=
|
||||
Postmortal=
|
||||
Use a Totem of Undying to cheat death.=
|
||||
Sweet Dreams=
|
||||
Sleep in a bed to change your respawn point.=
|
||||
Not Quite "Nine" Lives=
|
||||
Charge a Respawn Anchor to the maximum.=
|
||||
What A Deal!=
|
||||
Successfully trade with a Villager.=
|
||||
Fishy Business=
|
||||
Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=
|
||||
Country Lode,@nTake Me Home=
|
||||
Use a compass on a Lodestone.=
|
||||
Serious Dedication=
|
||||
Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=
|
||||
Local Brewery=
|
||||
Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=
|
||||
Enchanter=
|
||||
Enchant an item using an Enchantment Table.=
|
||||
|
|
|
@ -156,33 +156,20 @@ function mcl_experience.throw_xp(pos, total_xp)
|
|||
end
|
||||
end
|
||||
|
||||
function mcl_experience.update(player)
|
||||
local xp = mcl_experience.get_xp(player)
|
||||
local cache = caches[player]
|
||||
|
||||
cache.level = xp_to_level(xp)
|
||||
|
||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
||||
player:hud_change(hud_bars[player], "text", "mcl_experience_bar_background.png^[lowpart:"
|
||||
.. math.floor(math.floor(xp_to_bar(xp, cache.level) * 18) / 18 * 100)
|
||||
.. ":mcl_experience_bar.png^[transformR270"
|
||||
)
|
||||
|
||||
if cache.level == 0 then
|
||||
player:hud_change(hud_levels[player], "text", "")
|
||||
else
|
||||
player:hud_change(hud_levels[player], "text", tostring(cache.level))
|
||||
end
|
||||
function mcl_experience.remove_hud(player)
|
||||
if hud_bars[player] then
|
||||
player:hud_remove(hud_bars[player])
|
||||
hud_bars[player] = nil
|
||||
end
|
||||
if hud_levels[player] then
|
||||
player:hud_remove(hud_levels[player])
|
||||
hud_levels[player] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_experience.register_on_add_xp(func, priority)
|
||||
table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0})
|
||||
end
|
||||
|
||||
-- callbacks
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
function mcl_experience.setup_hud(player)
|
||||
if hud_bars[player] and hud_levels[player] then return end
|
||||
mcl_experience.remove_hud(player)
|
||||
caches[player] = {
|
||||
last_time = get_time(),
|
||||
}
|
||||
|
@ -205,7 +192,39 @@ minetest.register_on_joinplayer(function(player)
|
|||
z_index = 12,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_experience.update(player)
|
||||
local xp = mcl_experience.get_xp(player)
|
||||
local cache = caches[player]
|
||||
|
||||
cache.level = xp_to_level(xp)
|
||||
|
||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
||||
if not hud_bars[player] then
|
||||
mcl_experience.setup_hud(player)
|
||||
end
|
||||
player:hud_change(hud_bars[player], "text", "mcl_experience_bar_background.png^[lowpart:"
|
||||
.. math.floor(math.floor(xp_to_bar(xp, cache.level) * 18) / 18 * 100)
|
||||
.. ":mcl_experience_bar.png^[transformR270"
|
||||
)
|
||||
|
||||
if cache.level == 0 then
|
||||
player:hud_change(hud_levels[player], "text", "")
|
||||
else
|
||||
player:hud_change(hud_levels[player], "text", tostring(cache.level))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_experience.register_on_add_xp(func, priority)
|
||||
table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0})
|
||||
end
|
||||
|
||||
-- callbacks
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_experience.setup_hud(player)
|
||||
mcl_experience.update(player)
|
||||
end)
|
||||
|
||||
|
|
|
@ -206,6 +206,12 @@ local gamemodes = {
|
|||
function mcl_inventory.player_set_gamemode(p,g)
|
||||
local m = p:get_meta()
|
||||
m:set_string("gamemode",g)
|
||||
if g == "survival" then
|
||||
mcl_experience.setup_hud(p)
|
||||
mcl_experience.update(p)
|
||||
elseif g == "creative" then
|
||||
mcl_experience.remove_hud(p)
|
||||
end
|
||||
set_inventory(p)
|
||||
end
|
||||
|
||||
|
|
|
@ -59,8 +59,9 @@ minetest.register_globalstep(function(dtime)
|
|||
local itemstack = mcl_offhand.get_offhand(player)
|
||||
local offhand_item = itemstack:get_name()
|
||||
local offhand_hud = mcl_offhand[player].hud
|
||||
if offhand_item ~= "" then
|
||||
local item_texture = minetest.registered_items[offhand_item].inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px
|
||||
local item = minetest.registered_items[offhand_item]
|
||||
if offhand_item ~= "" and item then
|
||||
local item_texture = item.inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px
|
||||
local position = {x = 0.5, y = 1}
|
||||
local offset = {x = -320, y = -32}
|
||||
|
||||
|
|
|
@ -117,7 +117,6 @@ for _, def in pairs(bud_def) do
|
|||
walkable = false,
|
||||
light_source = def.light_source,
|
||||
groups = {
|
||||
dig_by_water = 1,
|
||||
destroy_by_lava_flow = 1,
|
||||
dig_by_piston = 1,
|
||||
pickaxey = 1,
|
||||
|
@ -162,7 +161,6 @@ minetest.register_node("mcl_amethyst:amethyst_cluster",{
|
|||
walkable = false,
|
||||
light_source = 7,
|
||||
groups = {
|
||||
dig_by_water = 1,
|
||||
destroy_by_lava_flow = 1,
|
||||
dig_by_piston = 1,
|
||||
pickaxey = 1,
|
||||
|
|
|
@ -84,6 +84,19 @@ local function distinguish_tool_and_material(input1, input2)
|
|||
end
|
||||
end
|
||||
|
||||
-- Helper function to make sure update_anvil_slots NEVER overstacks the output slot
|
||||
local function fix_stack_size(stack)
|
||||
if not stack or stack == "" then return "" end
|
||||
local count = stack:get_count()
|
||||
local max_count = stack:get_stack_max()
|
||||
|
||||
if count > max_count then
|
||||
stack:set_count(max_count)
|
||||
count = max_count
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
-- Update the inventory slots of an anvil node.
|
||||
-- meta: Metadata of anvil node
|
||||
local function update_anvil_slots(meta)
|
||||
|
@ -213,6 +226,7 @@ local function update_anvil_slots(meta)
|
|||
|
||||
-- Set the new output slot
|
||||
if new_output then
|
||||
fix_stack_size(new_output)
|
||||
inv:set_stack("output", 1, new_output)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,6 +114,10 @@ function mcl_armor.register_set(def)
|
|||
for k, v in pairs(element_groups) do
|
||||
groups[k] = v
|
||||
end
|
||||
local upgrade_item = nil
|
||||
if def._mcl_upgradable and def._mcl_upgrade_item_material then
|
||||
upgrade_item = itemstring:gsub("_[%l%d]*$",def._mcl_upgrade_item_material)
|
||||
end
|
||||
|
||||
minetest.register_tool(itemstring, {
|
||||
description = S(def.description .. " " .. (descriptions[name] or element.description)),
|
||||
|
@ -133,6 +137,8 @@ function mcl_armor.register_set(def)
|
|||
_on_break = on_break_callbacks[name] or def.on_break,
|
||||
_mcl_armor_element = name,
|
||||
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
||||
_mcl_upgradable = def._mcl_upgradable,
|
||||
_mcl_upgrade_item = upgrade_item
|
||||
})
|
||||
|
||||
if def.craft_material then
|
||||
|
|
|
@ -49,6 +49,8 @@ mcl_armor.register_set({
|
|||
},
|
||||
repair_material = "mcl_core:iron_ingot",
|
||||
cook_material = "mcl_core:iron_nugget",
|
||||
sound_equip = "mcl_armor_equip_iron",
|
||||
sound_unequip = "mcl_armor_unequip_iron",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
|
@ -64,6 +66,8 @@ mcl_armor.register_set({
|
|||
},
|
||||
craft_material = "mcl_core:iron_ingot",
|
||||
cook_material = "mcl_core:iron_nugget",
|
||||
sound_equip = "mcl_armor_equip_iron",
|
||||
sound_unequip = "mcl_armor_unequip_iron",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
|
@ -79,6 +83,27 @@ mcl_armor.register_set({
|
|||
},
|
||||
toughness = 2,
|
||||
craft_material = "mcl_core:diamond",
|
||||
sound_equip = "mcl_armor_equip_diamond",
|
||||
sound_unequip = "mcl_armor_unequip_diamond",
|
||||
_mcl_upgradable = true,
|
||||
_mcl_upgrade_item_material = "_netherite",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "netherite",
|
||||
description = "Netherite",
|
||||
durability = 555,
|
||||
enchantability = 10,
|
||||
points = {
|
||||
head = 3,
|
||||
torso = 8,
|
||||
legs = 6,
|
||||
feet = 3,
|
||||
},
|
||||
toughness = 2,
|
||||
craft_material = "mcl_nether:netherite_ingot",
|
||||
sound_equip = "mcl_armor_equip_diamond",
|
||||
sound_unequip = "mcl_armor_unequip_diamond",
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
|
|
After Width: | Height: | Size: 400 B |
After Width: | Height: | Size: 574 B |
After Width: | Height: | Size: 535 B |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 459 B |
|
@ -76,6 +76,7 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
|||
-- save respawn position when entering bed
|
||||
if spawn_mod and mcl_spawn.set_spawn_pos(player, bed_pos, nil) then
|
||||
minetest.chat_send_player(name, S("New respawn position set!"))
|
||||
awards.unlock(player:get_player_name(), "mcl:sweetDreams")
|
||||
end
|
||||
|
||||
-- No sleeping if too far away
|
||||
|
|
|
@ -39,6 +39,9 @@ for i=0,4 do
|
|||
elseif string.match(node.name, "mcl_beds:respawn_anchor_charged_") then
|
||||
minetest.chat_send_player(player.get_player_name(player), S"New respawn position set!")
|
||||
mcl_spawn.set_spawn_pos(player, pos, nil)
|
||||
if i == 4 then
|
||||
awards.unlock(player:get_player_name(), "mcl:notQuiteNineLives")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -88,11 +91,11 @@ for i=0,4 do
|
|||
end
|
||||
|
||||
|
||||
minetest.register_craft({ --TODO: Please change this crafting recipe once crying obsidian is implemented!
|
||||
minetest.register_craft({
|
||||
output = "mcl_beds:respawn_anchor",
|
||||
recipe = {
|
||||
{"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"},
|
||||
{"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"},
|
||||
{"mcl_nether:glowstone", "mcl_nether:glowstone", "mcl_nether:glowstone"},
|
||||
{"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}
|
||||
{"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -35,10 +35,14 @@ minetest.register_node("mcl_bells:bell", {
|
|||
is_ground_content = false,
|
||||
groups = {pickaxey=2, deco_block=1 },
|
||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||
_mcl_blast_resistance = 6,
|
||||
_mcl_blast_resistance = 5,
|
||||
_mcl_hardness = 5,
|
||||
on_rightclick = mcl_bells.ring_once,
|
||||
use_texture_alpha = "clip",
|
||||
mesecons = {effector = {
|
||||
action_on = mcl_bells.ring_once,
|
||||
rules = mesecon.rules.flat,
|
||||
}},
|
||||
})
|
||||
|
||||
if has_mcl_wip then
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
name = mcl_bells
|
||||
optional_depends = mcl_wip
|
||||
depends = mesecons
|
||||
optional_depends = mcl_wip
|
|
@ -13,8 +13,8 @@ minetest.register_node("mcl_blackstone:blackstone", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1, cobble=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 6,
|
||||
_mcl_hardness = 1.5,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:blackstone_gilded", {
|
||||
description = S("Gilded Blackstone"),
|
||||
|
@ -53,8 +53,8 @@ minetest.register_node("mcl_blackstone:nether_gold", {
|
|||
{items = {"mcl_blackstone:nether_gold"}, rarity = 8},
|
||||
}
|
||||
},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 3,
|
||||
_mcl_hardness = 3,
|
||||
_mcl_silk_touch_drop = true,
|
||||
_mcl_fortune_drop = mcl_core.fortune_drop_ore,
|
||||
})
|
||||
|
@ -67,8 +67,8 @@ minetest.register_node("mcl_blackstone:basalt_polished", {
|
|||
on_rotate = on_rotate,
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 4.2,
|
||||
_mcl_hardness = 1.25,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:basalt", {
|
||||
description = S("Basalt"),
|
||||
|
@ -79,8 +79,17 @@ minetest.register_node("mcl_blackstone:basalt", {
|
|||
on_rotate = on_rotate,
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 4.2,
|
||||
_mcl_hardness = 1.25,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:basalt_smooth", {
|
||||
description = S("Smooth Basalt"),
|
||||
tiles = {"mcl_blackstone_basalt_smooth.png"},
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 4.2,
|
||||
_mcl_hardness = 1.25,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:blackstone_polished", {
|
||||
description = S("Polished Blackstone"),
|
||||
|
@ -88,7 +97,7 @@ minetest.register_node("mcl_blackstone:blackstone_polished", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_blast_resistance = 6,
|
||||
_mcl_hardness = 2,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:blackstone_chiseled_polished", {
|
||||
|
@ -97,8 +106,8 @@ minetest.register_node("mcl_blackstone:blackstone_chiseled_polished", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 6,
|
||||
_mcl_hardness = 1.5,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:blackstone_brick_polished", {
|
||||
description = S("Polished Blackstone Bricks"),
|
||||
|
@ -106,8 +115,8 @@ minetest.register_node("mcl_blackstone:blackstone_brick_polished", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 6,
|
||||
_mcl_hardness = 1.5,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:quartz_brick", {
|
||||
description = S("Quartz Bricks"),
|
||||
|
@ -116,8 +125,8 @@ minetest.register_node("mcl_blackstone:quartz_brick", {
|
|||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
groups = {cracky = 3, pickaxey=2, material_stone=1},
|
||||
_mcl_blast_resistance = 2,
|
||||
_mcl_hardness = 2,
|
||||
_mcl_blast_resistance = 0.8,
|
||||
_mcl_hardness = 0.8,
|
||||
})
|
||||
minetest.register_node("mcl_blackstone:soul_soil", {
|
||||
description = S("Soul Soil"),
|
||||
|
@ -314,36 +323,7 @@ for s=1, #specialstones do
|
|||
end
|
||||
|
||||
if minetest.settings:get_bool("mcl_generate_ores", true) then
|
||||
minetest.register_ore({
|
||||
ore_type = "scatter",
|
||||
ore = "mcl_blackstone:blackstone_gilded",
|
||||
wherein = "mcl_blackstone:blackstone",
|
||||
clust_scarcity = 4775,
|
||||
clust_num_ores = 2,
|
||||
clust_size = 2,
|
||||
y_min = mcl_vars.mg_nether_min,
|
||||
y_max = mcl_vars.mg_nether_max,
|
||||
})
|
||||
minetest.register_ore({
|
||||
ore_type = "scatter",
|
||||
ore = "mcl_blackstone:nether_gold",
|
||||
wherein = "mcl_nether:netherrack",
|
||||
clust_scarcity = 830,
|
||||
clust_num_ores = 5,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_nether_min,
|
||||
y_max = mcl_vars.mg_nether_max,
|
||||
})
|
||||
minetest.register_ore({
|
||||
ore_type = "scatter",
|
||||
ore = "mcl_blackstone:nether_gold",
|
||||
wherein = "mcl_nether:netherrack",
|
||||
clust_scarcity = 1660,
|
||||
clust_num_ores = 4,
|
||||
clust_size = 2,
|
||||
y_min = mcl_vars.mg_nether_min,
|
||||
y_max = mcl_vars.mg_nether_max,
|
||||
})
|
||||
|
||||
end
|
||||
--]]
|
||||
--soul torch
|
||||
|
|
|
@ -288,7 +288,8 @@ local function blast_furnace_node_timer(pos, elapsed)
|
|||
-- Cooking
|
||||
--
|
||||
|
||||
local el = elapsed_game_time
|
||||
-- Run the blast_furnace at twice the speed of a furnace.
|
||||
local el = elapsed_game_time * 2
|
||||
|
||||
-- Check if we have cookable content: cookable
|
||||
local aftercooked
|
||||
|
@ -329,13 +330,12 @@ local function blast_furnace_node_timer(pos, elapsed)
|
|||
elseif active then
|
||||
el = math.min(el, fuel_totaltime - fuel_time)
|
||||
-- The furnace is currently active and has enough fuel
|
||||
fuel_time = (fuel_time + el) *2 --multiply speed of fuel consumption to match proper output
|
||||
fuel_time = fuel_time + el
|
||||
end
|
||||
|
||||
-- If there is a cookable item then check if it is ready yet
|
||||
if cookable and active then
|
||||
-- In the src_time variable, the *2 is the multiplication that makes the blast furnace work faster than a normal furnace.
|
||||
src_time = (src_time + el)*2
|
||||
src_time = src_time + el
|
||||
-- Place result in dst list if done
|
||||
if src_time >= cooked.time then
|
||||
inv:add_item("dst", cooked.item)
|
||||
|
|