Merge pull request 'merge beacon-branch into fork beacon branch' (#7) from MineClone2/MineClone2:beacons into beacon-"fork"
Reviewed-on: #7
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`
|
* Buckets: `ITEMS/mcl_buckets`
|
||||||
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
||||||
|
|
||||||
## Mobs
|
### Mobs
|
||||||
* Mobs: `ENTITIES/mcl_mobs`
|
* Mobs: `ENTITIES/mcl_mobs`
|
||||||
|
|
||||||
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
|
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
|
||||||
|
|
16
CREDITS.md
|
@ -27,6 +27,10 @@
|
||||||
* Code-Sploit
|
* Code-Sploit
|
||||||
* NO11
|
* NO11
|
||||||
* kabou
|
* kabou
|
||||||
|
* rudzik8
|
||||||
|
* chmodsayshello
|
||||||
|
* PrarieWind
|
||||||
|
* RandomLegoBrick
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
* Laurent Rocher
|
* Laurent Rocher
|
||||||
|
@ -71,6 +75,10 @@
|
||||||
* Sven792
|
* Sven792
|
||||||
* aldum
|
* aldum
|
||||||
* Dieter44
|
* Dieter44
|
||||||
|
* Pepebotella
|
||||||
|
* MrRar
|
||||||
|
* Lazerbeak12345
|
||||||
|
* mrminer
|
||||||
|
|
||||||
## MineClone5
|
## MineClone5
|
||||||
* kay27
|
* kay27
|
||||||
|
@ -78,10 +86,12 @@
|
||||||
* epCode
|
* epCode
|
||||||
* NO11
|
* NO11
|
||||||
* j45
|
* j45
|
||||||
|
* chmodsayshello
|
||||||
* 3raven
|
* 3raven
|
||||||
* PrarieWind
|
* PrarieWind
|
||||||
* Gustavo1
|
* Gustavo1
|
||||||
* CableGuy67
|
* CableGuy67
|
||||||
|
* MrRar
|
||||||
|
|
||||||
## Mineclonia
|
## Mineclonia
|
||||||
* erlehmann
|
* erlehmann
|
||||||
|
@ -134,6 +144,9 @@
|
||||||
* yutyo
|
* yutyo
|
||||||
* NO11
|
* NO11
|
||||||
* kay27
|
* kay27
|
||||||
|
* MysticTempest
|
||||||
|
* RandomLegoBrick
|
||||||
|
* cora
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
* Wuzzy
|
* Wuzzy
|
||||||
|
@ -143,6 +156,8 @@
|
||||||
* pitchum
|
* pitchum
|
||||||
* todoporlalibertad
|
* todoporlalibertad
|
||||||
* Marcin Serwin
|
* Marcin Serwin
|
||||||
|
* Pepebotella
|
||||||
|
* Emojigit
|
||||||
|
|
||||||
## Funders
|
## Funders
|
||||||
* 40W
|
* 40W
|
||||||
|
@ -150,5 +165,6 @@
|
||||||
## Special thanks
|
## Special thanks
|
||||||
* celeron55 for creating Minetest
|
* celeron55 for creating Minetest
|
||||||
* Jordach for the jukebox music compilation from Big Freaking Dig
|
* Jordach for the jukebox music compilation from Big Freaking Dig
|
||||||
|
* wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues.
|
||||||
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
|
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
|
||||||
* Notch and Jeb for being the major forces behind Minecraft
|
* Notch and Jeb for being the major forces behind Minecraft
|
||||||
|
|
18
README.md
|
@ -2,7 +2,7 @@
|
||||||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
||||||
Developed by many people. Not developed or endorsed by Mojang AB.
|
Developed by many people. Not developed or endorsed by Mojang AB.
|
||||||
|
|
||||||
Version: 0.75 (in development)
|
Version: 0.78 (in development)
|
||||||
|
|
||||||
### Gameplay
|
### Gameplay
|
||||||
You start in a randomly-generated world made entirely of cubes. You can explore
|
You start in a randomly-generated world made entirely of cubes. You can explore
|
||||||
|
@ -91,11 +91,11 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues,
|
||||||
## Target
|
## Target
|
||||||
- Crucially, create a stable, moddable, free/libre clone of Minecraft
|
- Crucially, create a stable, moddable, free/libre clone of Minecraft
|
||||||
based on the Minetest engine with polished features, usable in both
|
based on the Minetest engine with polished features, usable in both
|
||||||
singleplayer and multiplayer. Currently, most of **Minecraft Java
|
singleplayer and multiplayer. Currently, a lot of **Minecraft Java
|
||||||
Edition 1.12.2** features are already implemented and polishing existing
|
Edition** features are already implemented and polishing existing
|
||||||
features are prioritized over new feature requests.
|
features are prioritized over new feature requests.
|
||||||
- With lessened priority yet strictly, implement features targetting
|
- With lessened priority yet strictly, implement features targetting
|
||||||
**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
|
by the Minetest Engine). This means features in parity with the listed
|
||||||
Minecraft experiences are prioritized over those that don't fulfill this
|
Minecraft experiences are prioritized over those that don't fulfill this
|
||||||
scope.
|
scope.
|
||||||
|
@ -108,8 +108,7 @@ playerbase on low spec computers, optimizations are hard to investigate.
|
||||||
This game is currently in **beta** stage.
|
This game is currently in **beta** stage.
|
||||||
It is playable, but not yet feature-complete.
|
It is playable, but not yet feature-complete.
|
||||||
Backwards-compability is not entirely guaranteed, updating your world might cause small bugs.
|
Backwards-compability is not entirely guaranteed, updating your world might cause small bugs.
|
||||||
If you want to use the git version of MineClone2 in production, consider using the production branch.
|
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.
|
||||||
It is updated weekly and contains relatively stable code for servers.
|
|
||||||
|
|
||||||
The following main features are available:
|
The following main features are available:
|
||||||
|
|
||||||
|
@ -124,7 +123,7 @@ The following main features are available:
|
||||||
* Most blocks in the overworld
|
* Most blocks in the overworld
|
||||||
* Water and lava
|
* Water and lava
|
||||||
* Weather
|
* Weather
|
||||||
* 28 biomes
|
* 28 biomes + 5 Nether Biomes
|
||||||
* The Nether, a fiery underworld in another dimension
|
* The Nether, a fiery underworld in another dimension
|
||||||
* Redstone circuits (partially)
|
* Redstone circuits (partially)
|
||||||
* Minecarts (partial)
|
* Minecarts (partial)
|
||||||
|
@ -162,7 +161,7 @@ The following features are incomplete:
|
||||||
* Special minecarts
|
* Special minecarts
|
||||||
* A couple of non-trivial blocks and items
|
* A couple of non-trivial blocks and items
|
||||||
|
|
||||||
Bonus features (not found in Minecraft 1.12):
|
Bonus features (not found in Minecraft):
|
||||||
|
|
||||||
* Built-in crafting guide which shows you crafting and smelting recipes
|
* Built-in crafting guide which shows you crafting and smelting recipes
|
||||||
* In-game help system containing extensive help about gameplay basics, blocks, items and more
|
* In-game help system containing extensive help about gameplay basics, blocks, items and more
|
||||||
|
@ -175,6 +174,9 @@ Bonus features (not found in Minecraft 1.12):
|
||||||
* Nether Brick Fence Gate
|
* Nether Brick Fence Gate
|
||||||
* Red Nether Brick Fence
|
* Red Nether Brick Fence
|
||||||
* Red Nether Brick Fence Gate
|
* Red Nether Brick Fence Gate
|
||||||
|
* Structure replacements - these small variants of Minecraft structures serve as replacements until we can get large structures working:
|
||||||
|
* Woodland Cabin (Mansions)
|
||||||
|
* Nether Outpost (Fortress)
|
||||||
|
|
||||||
Technical differences from Minecraft:
|
Technical differences from Minecraft:
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
name = MineClone 2
|
title = MineClone 2
|
||||||
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
||||||
|
|
|
@ -110,9 +110,11 @@ end
|
||||||
|
|
||||||
local boat = {
|
local boat = {
|
||||||
physical = true,
|
physical = true,
|
||||||
|
pointable = true,
|
||||||
-- Warning: Do not change the position of the collisionbox top surface,
|
-- Warning: Do not change the position of the collisionbox top surface,
|
||||||
-- lowering it causes the boat to fall through the world if underwater
|
-- lowering it causes the boat to fall through the world if underwater
|
||||||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||||
|
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mcl_boats_boat.b3d",
|
mesh = "mcl_boats_boat.b3d",
|
||||||
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
||||||
|
|
|
@ -134,6 +134,7 @@ function mcl_burning.set_on_fire(obj, burn_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_burning.extinguish(obj)
|
function mcl_burning.extinguish(obj)
|
||||||
|
if not obj:get_pos() then return end
|
||||||
if mcl_burning.is_burning(obj) then
|
if mcl_burning.is_burning(obj) then
|
||||||
local storage = mcl_burning.get_storage(obj)
|
local storage = mcl_burning.get_storage(obj)
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
|
|
|
@ -1,66 +1,55 @@
|
||||||
-- Dripping Water Mod
|
-- Dripping Water Mod
|
||||||
-- by kddekadenz
|
-- by kddekadenz
|
||||||
|
|
||||||
local math = math
|
|
||||||
|
|
||||||
-- License of code, textures & sounds: CC0
|
-- License of code, textures & sounds: CC0
|
||||||
|
|
||||||
local function register_drop(liquid, glow, sound, nodes)
|
local math = math
|
||||||
minetest.register_entity("mcl_dripping:drop_" .. liquid, {
|
local function make_drop(pos,liquid,sound,interval)
|
||||||
hp_max = 1,
|
local pt = {
|
||||||
physical = true,
|
velocity = vector.new(0,0,0),
|
||||||
collide_with_objects = false,
|
collision_removal = false,
|
||||||
collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01},
|
}
|
||||||
glow = glow,
|
local t = math.random() + math.random(1, interval)
|
||||||
pointable = false,
|
minetest.after(t,function()
|
||||||
visual = "sprite",
|
local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
|
||||||
visual_size = {x = 0.1, y = 0.1},
|
pt.pos = vector.offset(pos,x,-0.52,z)
|
||||||
textures = {""},
|
pt.acceleration = vector.new(0,0,0)
|
||||||
spritediv = {x = 1, y = 1},
|
pt.collisiondetection = false
|
||||||
initial_sprite_basepos = {x = 0, y = 0},
|
pt.expirationtime = t
|
||||||
static_save = false,
|
|
||||||
_dropped = false,
|
pt.texture="[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"
|
||||||
on_activate = function(self)
|
minetest.add_particle(pt)
|
||||||
self.object:set_properties({
|
minetest.after(t,function()
|
||||||
textures = {"[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"}
|
pt.acceleration = vector.new(0,-5,0)
|
||||||
})
|
pt.collisiondetection = true
|
||||||
end,
|
pt.expirationtime = math.random() + math.random(1, interval/2)
|
||||||
on_step = function(self, dtime)
|
minetest.add_particle(pt)
|
||||||
local k = math.random(1, 222)
|
minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = pos, gain = 0.5, max_hear_distance = 8}, true)
|
||||||
local ownpos = self.object:get_pos()
|
end)
|
||||||
if k == 1 then
|
end)
|
||||||
self.object:set_acceleration(vector.new(0, -5, 0))
|
|
||||||
end
|
end
|
||||||
if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then
|
|
||||||
self.object:set_acceleration(vector.new(0, -5, 0))
|
local function register_drop(liquid, glow, sound, nodes, interval, chance)
|
||||||
end
|
|
||||||
if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then
|
|
||||||
local ent = self.object:get_luaentity()
|
|
||||||
if not ent._dropped then
|
|
||||||
ent._dropped = true
|
|
||||||
minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
|
||||||
end
|
|
||||||
if k < 3 then
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "Create drops",
|
label = "Create drops",
|
||||||
nodenames = nodes,
|
nodenames = nodes,
|
||||||
neighbors = {"group:" .. liquid},
|
neighbors = {"group:" .. liquid},
|
||||||
interval = 2,
|
interval = interval,
|
||||||
chance = 22,
|
chance = chance,
|
||||||
action = function(pos)
|
action = function(pos)
|
||||||
if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0
|
local r = math.ceil(interval / 20)
|
||||||
and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then
|
local nn=minetest.find_nodes_in_area(vector.offset(pos,-r,0,-r),vector.offset(pos,r,0,r),nodes)
|
||||||
local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
|
--start a bunch of particle cycles to be able to get away
|
||||||
minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid)
|
--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,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
register_drop("water", 1, "", {"group:opaque", "group:leaves"})
|
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"})
|
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:blaze_rod", "mcl:blazeRod")
|
||||||
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
|
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
|
||||||
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
|
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
|
||||||
|
mcl_item_entity.register_pickup_achievement("mcl_core:crying_obsidian", "mcl:whosCuttingOnions")
|
||||||
|
mcl_item_entity.register_pickup_achievement("mcl_nether:ancient_debris", "mcl:hiddenInTheDepths")
|
||||||
|
|
||||||
local function check_pickup_achievements(object, player)
|
local function check_pickup_achievements(object, player)
|
||||||
if has_awards then
|
if has_awards then
|
||||||
|
@ -78,7 +80,6 @@ local function enable_physics(object, luaentity, ignore_check)
|
||||||
object:set_properties({
|
object:set_properties({
|
||||||
physical = true
|
physical = true
|
||||||
})
|
})
|
||||||
object:set_velocity({x=0,y=0,z=0})
|
|
||||||
object:set_acceleration({x=0,y=-get_gravity(),z=0})
|
object:set_acceleration({x=0,y=-get_gravity(),z=0})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -536,9 +537,9 @@ minetest.register_entity(":__builtin:item", {
|
||||||
self.itemstring = data.itemstring
|
self.itemstring = data.itemstring
|
||||||
self.always_collect = data.always_collect
|
self.always_collect = data.always_collect
|
||||||
if data.age then
|
if data.age then
|
||||||
self.age = data.age + dtime_s
|
self.age = data.age
|
||||||
else
|
else
|
||||||
self.age = dtime_s
|
self.age = self.age
|
||||||
end
|
end
|
||||||
--remember collection data
|
--remember collection data
|
||||||
-- If true, can collect item without delay
|
-- If true, can collect item without delay
|
||||||
|
@ -774,8 +775,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Move item around on flowing liquids
|
-- 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" then
|
if def and def.liquidtype == "flowing" or def.liquidtype == "source" then
|
||||||
|
|
||||||
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
|
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
|
||||||
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
|
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
|
||||||
|
@ -784,11 +785,11 @@ minetest.register_entity(":__builtin:item", {
|
||||||
-- Just to make sure we don't manipulate the speed for no reason
|
-- Just to make sure we don't manipulate the speed for no reason
|
||||||
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
|
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
|
||||||
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
|
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
|
||||||
local f = 1.39
|
local f = 1.2
|
||||||
-- Set new item moving speed into the direciton of the liquid
|
-- Set new item moving speed into the direciton of the liquid
|
||||||
local newv = vector.multiply(vec, f)
|
local newv = vector.multiply(vec, f)
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
-- Swap to acceleration instead of a static speed to better mimic MC mechanics.
|
||||||
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
|
self.object:set_acceleration({x = newv.x, y = -0.22, z = newv.z})
|
||||||
|
|
||||||
self.physical_state = true
|
self.physical_state = true
|
||||||
self._flowing = 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 nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||||
local v = self.object:get_velocity()
|
local v = self.object: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
|
if self.physical_state then
|
||||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||||
-- Merge with close entities of the same item
|
-- Merge with close entities of the same item
|
||||||
|
|
|
@ -21,7 +21,7 @@ local function register_rail(itemstring, tiles, def_extras, creative)
|
||||||
stack_max = 64,
|
stack_max = 64,
|
||||||
groups = groups,
|
groups = groups,
|
||||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||||
_mcl_blast_resistance = 3.5,
|
_mcl_blast_resistance = 0.7,
|
||||||
_mcl_hardness = 0.7,
|
_mcl_hardness = 0.7,
|
||||||
after_destruct = function(pos)
|
after_destruct = function(pos)
|
||||||
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
||||||
|
|
|
@ -91,7 +91,7 @@ minetest.register_chatcommand("clearmobs",{
|
||||||
if o.is_mob then
|
if o.is_mob then
|
||||||
if param == "all" or
|
if param == "all" or
|
||||||
( param == "nametagged" and o.nametag ) 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
|
( num and num > 0 and vector.distance(p:get_pos(),o.object:get_pos()) <= num ) then
|
||||||
o.object:remove()
|
o.object:remove()
|
||||||
end
|
end
|
||||||
|
@ -298,9 +298,13 @@ local function update_roll(self)
|
||||||
|
|
||||||
if is_Fleckenstein then
|
if is_Fleckenstein then
|
||||||
cbox[2], cbox[5] = -cbox[5], -cbox[2]
|
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
|
end
|
||||||
|
|
||||||
self.object:set_properties({collisionbox = cbox})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set and return valid yaw
|
-- set and return valid yaw
|
||||||
|
@ -1901,11 +1905,10 @@ local specific_attack = function(list, what)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- monster find someone to attack
|
-- find someone to attack
|
||||||
local monster_attack = function(self)
|
local monster_attack = function(self)
|
||||||
|
|
||||||
if self.type ~= "monster"
|
if not damage_enabled
|
||||||
or not damage_enabled
|
|
||||||
or minetest.is_creative_enabled("")
|
or minetest.is_creative_enabled("")
|
||||||
or self.passive
|
or self.passive
|
||||||
or self.state == "attack"
|
or self.state == "attack"
|
||||||
|
@ -1923,10 +1926,9 @@ local monster_attack = function(self)
|
||||||
for n = 1, #objs do
|
for n = 1, #objs do
|
||||||
|
|
||||||
if objs[n]:is_player() then
|
if objs[n]:is_player() then
|
||||||
|
|
||||||
if mcl_mobs.invis[ objs[n]:get_player_name() ] or (not object_in_range(self, objs[n])) then
|
if mcl_mobs.invis[ objs[n]:get_player_name() ] or (not object_in_range(self, objs[n])) then
|
||||||
type = ""
|
type = ""
|
||||||
else
|
elseif (self.type == "monster" or self._aggro) then
|
||||||
player = objs[n]
|
player = objs[n]
|
||||||
type = "player"
|
type = "player"
|
||||||
name = "player"
|
name = "player"
|
||||||
|
@ -2283,6 +2285,9 @@ end
|
||||||
local function go_to_pos(entity,b)
|
local function go_to_pos(entity,b)
|
||||||
if not entity then return end
|
if not entity then return end
|
||||||
local s=entity.object:get_pos()
|
local s=entity.object:get_pos()
|
||||||
|
if not b then
|
||||||
|
--self.state = "stand"
|
||||||
|
return end
|
||||||
if vector.distance(b,s) < 1 then
|
if vector.distance(b,s) < 1 then
|
||||||
--set_velocity(entity,0)
|
--set_velocity(entity,0)
|
||||||
return true
|
return true
|
||||||
|
@ -2305,15 +2310,52 @@ local function check_doors(self)
|
||||||
local def = minetest.registered_nodes[n.name]
|
local def = minetest.registered_nodes[n.name]
|
||||||
local closed = n.name:find("_b_1")
|
local closed = n.name:find("_b_1")
|
||||||
if t < 0.3 or t > 0.8 then
|
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
|
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
|
||||||
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)
|
-- execute current state (stand, walk, run, attacks)
|
||||||
-- returns true if mob has died
|
-- returns true if mob has died
|
||||||
local do_states = function(self, dtime)
|
local do_states = function(self, dtime)
|
||||||
|
@ -2326,9 +2368,8 @@ local do_states = function(self, dtime)
|
||||||
|
|
||||||
local s = self.object:get_pos()
|
local s = self.object:get_pos()
|
||||||
local objs = minetest.get_objects_inside_radius(s, 3)
|
local objs = minetest.get_objects_inside_radius(s, 3)
|
||||||
|
local lp
|
||||||
for n = 1, #objs do
|
for n = 1, #objs do
|
||||||
|
|
||||||
if objs[n]:is_player() then
|
if objs[n]:is_player() then
|
||||||
lp = objs[n]:get_pos()
|
lp = objs[n]:get_pos()
|
||||||
break
|
break
|
||||||
|
@ -2336,7 +2377,7 @@ local do_states = function(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- look at any players nearby, otherwise turn randomly
|
-- look at any players nearby, otherwise turn randomly
|
||||||
if self.look_at_players then
|
if lp and self.look_at_players then
|
||||||
|
|
||||||
local vec = {
|
local vec = {
|
||||||
x = lp.x - s.x,
|
x = lp.x - s.x,
|
||||||
|
@ -2372,32 +2413,7 @@ local do_states = function(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif self.state == "gowp" then
|
elseif self.state == "gowp" then
|
||||||
local p = self.object:get_pos()
|
check_gowp(self,dtime)
|
||||||
if not p or not self._target then return end
|
|
||||||
if vector.distance(p,self._target) < 2 or ( self.waypoints and #self.waypoints == 0 ) then
|
|
||||||
self.waypoints = nil
|
|
||||||
self._target = nil
|
|
||||||
self.current_target = nil
|
|
||||||
self.state = "walk"
|
|
||||||
if self.callback_arrived then return self.callback_arrived(self) end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 1.5 ) then
|
|
||||||
self.current_target = table.remove(self.waypoints, 1)
|
|
||||||
--minetest.log("nextwp:".. tostring(self.current_target) )
|
|
||||||
elseif self.current_target then
|
|
||||||
go_to_pos(self,self.current_target)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then
|
|
||||||
self.waypoints=minetest.find_path(p,self._target,150,1,4)
|
|
||||||
self.current_target = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not self.current_target then
|
|
||||||
--minetest.log("no path")
|
|
||||||
self.state = "walk"
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif self.state == "walk" then
|
elseif self.state == "walk" then
|
||||||
local s = self.object:get_pos()
|
local s = self.object:get_pos()
|
||||||
|
@ -2908,7 +2924,12 @@ local plane_adjacents = {
|
||||||
vector.new(0,0,-1),
|
vector.new(0,0,-1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local gopath_last = os.time()
|
||||||
function mcl_mobs:gopath(self,target,callback_arrived)
|
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 p = self.object:get_pos()
|
||||||
local t = vector.offset(target,0,1,0)
|
local t = vector.offset(target,0,1,0)
|
||||||
local wp = minetest.find_path(p,t,150,1,4)
|
local wp = minetest.find_path(p,t,150,1,4)
|
||||||
|
@ -2928,10 +2949,14 @@ function mcl_mobs:gopath(self,target,callback_arrived)
|
||||||
if wp and #wp > 0 then
|
if wp and #wp > 0 then
|
||||||
self._target = t
|
self._target = t
|
||||||
self.callback_arrived = callback_arrived
|
self.callback_arrived = callback_arrived
|
||||||
|
table.remove(wp,1)
|
||||||
self.waypoints = wp
|
self.waypoints = wp
|
||||||
self.state = "gowp"
|
self.state = "gowp"
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
self.state = "walk"
|
||||||
|
self.waypoints = nil
|
||||||
|
self.current_target = nil
|
||||||
-- minetest.log("no path found")
|
-- minetest.log("no path found")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2964,7 +2989,7 @@ local function damage_mob(self,reason,damage)
|
||||||
if damage > 0 then
|
if damage > 0 then
|
||||||
self.health = self.health - damage
|
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
|
if check_for_death(self, reason, {type = reason}) then
|
||||||
return true
|
return true
|
||||||
|
@ -3210,9 +3235,10 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
|
|
||||||
local die = false
|
local die = false
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
-- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately.
|
||||||
if damage >= 0.1 then
|
if damage >= 0.1 then
|
||||||
|
|
||||||
-- weapon sounds
|
-- weapon sounds
|
||||||
if weapon:get_definition().sounds ~= nil then
|
if weapon:get_definition().sounds ~= nil then
|
||||||
|
|
||||||
|
@ -3238,7 +3264,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
if check_for_death(self, "hit", {type = "punch", puncher = hitter}) then
|
if check_for_death(self, "hit", {type = "punch", puncher = hitter}) then
|
||||||
die = true
|
die = true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
-- knock back effect (only on full punch)
|
-- knock back effect (only on full punch)
|
||||||
if not die
|
if not die
|
||||||
and self.knock_back
|
and self.knock_back
|
||||||
|
@ -3318,11 +3344,11 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
and (self.child == false or self.type == "monster")
|
and (self.child == false or self.type == "monster")
|
||||||
and hitter:get_player_name() ~= self.owner
|
and hitter:get_player_name() ~= self.owner
|
||||||
and not mcl_mobs.invis[ name ] then
|
and not mcl_mobs.invis[ name ] then
|
||||||
|
|
||||||
if not die then
|
if not die then
|
||||||
-- attack whoever punched mob
|
-- attack whoever punched mob
|
||||||
self.state = ""
|
self.state = ""
|
||||||
do_attack(self, hitter)
|
do_attack(self, hitter)
|
||||||
|
self._aggro= true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- alert others to the attack
|
-- alert others to the attack
|
||||||
|
@ -3334,7 +3360,6 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
obj = objs[n]:get_luaentity()
|
obj = objs[n]:get_luaentity()
|
||||||
|
|
||||||
if obj then
|
if obj then
|
||||||
|
|
||||||
-- only alert members of same mob or friends
|
-- only alert members of same mob or friends
|
||||||
if obj.group_attack
|
if obj.group_attack
|
||||||
and obj.state ~= "attack"
|
and obj.state ~= "attack"
|
||||||
|
@ -3344,6 +3369,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
elseif type(obj.group_attack) == "table" then
|
elseif type(obj.group_attack) == "table" then
|
||||||
for i=1, #obj.group_attack do
|
for i=1, #obj.group_attack do
|
||||||
if obj.name == obj.group_attack[i] then
|
if obj.name == obj.group_attack[i] then
|
||||||
|
obj._aggro = true
|
||||||
do_attack(obj, hitter)
|
do_attack(obj, hitter)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -4008,6 +4034,8 @@ minetest.register_entity(name, {
|
||||||
fire_resistant = def.fire_resistant or false,
|
fire_resistant = def.fire_resistant or false,
|
||||||
fire_damage_resistant = def.fire_damage_resistant or false,
|
fire_damage_resistant = def.fire_damage_resistant or false,
|
||||||
ignited_by_sunlight = def.ignited_by_sunlight 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
|
-- End of MCL2 extensions
|
||||||
|
|
||||||
on_spawn = def.on_spawn,
|
on_spawn = def.on_spawn,
|
||||||
|
@ -4333,7 +4361,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- feeding, taming and breeding (thanks blert2112)
|
-- 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
|
if not self.follow then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -4346,7 +4374,7 @@ function mcl_mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||||
|
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
|
|
||||||
item:take_item()
|
if not notake then item:take_item() end
|
||||||
|
|
||||||
clicker:set_wielded_item(item)
|
clicker:set_wielded_item(item)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,7 @@ local math_cos = math.cos
|
||||||
local math_sin = math.sin
|
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 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_new = vector.new
|
||||||
local vector_floor = vector.floor
|
local vector_floor = vector.floor
|
||||||
|
|
||||||
|
@ -25,7 +25,15 @@ local table_remove = table.remove
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
|
|
||||||
-- range for mob count
|
-- 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?
|
--do mobs spawn?
|
||||||
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
|
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
|
||||||
|
@ -153,6 +161,10 @@ local list_of_all_biomes = {
|
||||||
-- dimension biome:
|
-- dimension biome:
|
||||||
|
|
||||||
"Nether",
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
|
"CrimsonForest",
|
||||||
|
"WarpedForest",
|
||||||
|
"SoulsandValley",
|
||||||
"End",
|
"End",
|
||||||
|
|
||||||
-- Overworld regular:
|
-- Overworld regular:
|
||||||
|
@ -162,6 +174,8 @@ local list_of_all_biomes = {
|
||||||
"Swampland",
|
"Swampland",
|
||||||
"Taiga",
|
"Taiga",
|
||||||
"ExtremeHills",
|
"ExtremeHills",
|
||||||
|
"ExtremeHillsM",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
"Jungle",
|
"Jungle",
|
||||||
"Savanna",
|
"Savanna",
|
||||||
"BirchForest",
|
"BirchForest",
|
||||||
|
@ -180,7 +194,6 @@ local list_of_all_biomes = {
|
||||||
"ExtremeHills+_snowtop",
|
"ExtremeHills+_snowtop",
|
||||||
"MesaPlateauFM_grasstop",
|
"MesaPlateauFM_grasstop",
|
||||||
"JungleEdgeM",
|
"JungleEdgeM",
|
||||||
"ExtremeHillsM",
|
|
||||||
"JungleM",
|
"JungleM",
|
||||||
"BirchForestM",
|
"BirchForestM",
|
||||||
"MesaPlateauF",
|
"MesaPlateauF",
|
||||||
|
@ -192,13 +205,28 @@ local list_of_all_biomes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
-- count how many mobs are in an area
|
-- count how many mobs are in an area
|
||||||
local function count_mobs(pos)
|
local function count_mobs(pos,r,mob_type)
|
||||||
local num = 0
|
local num = 0
|
||||||
for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do
|
for _,l in pairs(minetest.luaentities) do
|
||||||
if object and object:get_luaentity() and object:get_luaentity().is_mob then
|
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
|
num = num + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
return num
|
||||||
|
end
|
||||||
|
|
||||||
|
local function count_mobs_total(mob_type)
|
||||||
|
local num = 0
|
||||||
|
for _,l in pairs(minetest.luaentities) do
|
||||||
|
if l.is_mob then
|
||||||
|
if mob_type == nil or l.type == mob_type then
|
||||||
|
num = num + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
return num
|
return num
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -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"
|
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
|
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
|
if mobs_spawn then
|
||||||
|
|
||||||
local perlin_noise
|
local perlin_noise
|
||||||
|
|
||||||
local function spawn_a_mob(pos, dimension, y_min, y_max)
|
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 dimension = dimension or mcl_worlds.pos_to_dimension(pos)
|
||||||
local goal_pos = get_next_mob_spawn_pos(pos)
|
local goal_pos = get_next_mob_spawn_pos(pos)
|
||||||
local spawning_position_list = find_nodes_in_area_under_air(
|
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
|
if #spawning_position_list <= 0 then return end
|
||||||
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
|
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_node = get_node(spawning_position).name
|
||||||
local gotten_biome = minetest.get_biome_data(spawning_position)
|
local gotten_biome = minetest.get_biome_data(spawning_position)
|
||||||
if not gotten_node or not gotten_biome then return end
|
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_water = get_item_group(gotten_node, "water") ~= 0
|
||||||
local is_lava = get_item_group(gotten_node, "lava") ~= 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_ground = not (is_water or is_lava)
|
||||||
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
|
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
|
||||||
local has_bed = minetest.find_node_near(pos,25,{"group:bed"})
|
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)
|
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
|
||||||
local noise = perlin_noise:get_3d(spawning_position)
|
local noise = perlin_noise:get_3d(spawning_position)
|
||||||
local current_summary_chance = summary_chance
|
local current_summary_chance = summary_chance
|
||||||
|
table.shuffle(mob_library_worker_table)
|
||||||
while #mob_library_worker_table > 0 do
|
while #mob_library_worker_table > 0 do
|
||||||
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
|
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
|
||||||
local mob_index = 1
|
local mob_index = 1
|
||||||
|
@ -438,7 +507,12 @@ if mobs_spawn then
|
||||||
end
|
end
|
||||||
local mob_def = mob_library_worker_table[mob_index]
|
local mob_def = mob_library_worker_table[mob_index]
|
||||||
local mob_type = minetest.registered_entities[mob_def.name].type
|
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
|
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.min_height
|
||||||
and spawning_position.y <= mob_def.max_height
|
and spawning_position.y <= mob_def.max_height
|
||||||
and mob_def.dimension == dimension
|
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.min_light
|
||||||
and gotten_light <= mob_def.max_light
|
and gotten_light <= mob_def.max_light
|
||||||
and (is_ground or mob_def.type_of_spawning ~= "ground")
|
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 (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 (not is_farm_animal(mob_def.name) or is_grass)
|
||||||
and (mob_type ~= "npc" or has_bed)
|
and (mob_type ~= "npc" or has_bed)
|
||||||
|
and (mob_def.type_of_spawning ~= "water" or is_water)
|
||||||
|
and not is_bedrock
|
||||||
then
|
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
|
--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
|
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
|
||||||
end
|
end
|
||||||
current_summary_chance = current_summary_chance - mob_chance
|
current_summary_chance = current_summary_chance - mob_chance
|
||||||
|
|
|
@ -46,6 +46,9 @@ end
|
||||||
local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"]
|
local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"]
|
||||||
local old_on_place = wither_head.on_place
|
local old_on_place = wither_head.on_place
|
||||||
function wither_head.on_place(itemstack, placer, pointed)
|
function wither_head.on_place(itemstack, placer, pointed)
|
||||||
|
local n = minetest.get_node(vector.offset(pointed.above,0,-1,0))
|
||||||
|
if n and n.name == "mcl_nether:soul_sand" then
|
||||||
minetest.after(0, wither_spawn, pointed.above)
|
minetest.after(0, wither_spawn, pointed.above)
|
||||||
old_on_place(itemstack, placer, pointed)
|
end
|
||||||
|
return old_on_place(itemstack, placer, pointed)
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ mcl_mobs:register_mob("mobs_mc:bat", {
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "ambient",
|
spawn_class = "ambient",
|
||||||
can_despawn = true,
|
can_despawn = true,
|
||||||
|
spawn_in_group = 8,
|
||||||
passive = true,
|
passive = true,
|
||||||
hp_min = 6,
|
hp_min = 6,
|
||||||
hp_max = 6,
|
hp_max = 6,
|
||||||
|
|
|
@ -16,6 +16,8 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
|
||||||
description = S("Blaze"),
|
description = S("Blaze"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
spawn_in_group_min = 2,
|
||||||
|
spawn_in_group = 3,
|
||||||
hp_min = 20,
|
hp_min = 20,
|
||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
xp_min = 10,
|
xp_min = 10,
|
||||||
|
|
|
@ -122,8 +122,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"ExtremeHills+",
|
"ExtremeHills+",
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
"StoneBeach",
|
|
||||||
"Plains",
|
"Plains",
|
||||||
"Plains_beach",
|
"Plains_beach",
|
||||||
"SunflowerPlains",
|
"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)
|
|
@ -83,6 +83,8 @@ mcl_mobs:register_mob("mobs_mc:cow", cow_def)
|
||||||
local mooshroom_def = table.copy(cow_def)
|
local mooshroom_def = table.copy(cow_def)
|
||||||
mooshroom_def.description = S("Mooshroom")
|
mooshroom_def.description = S("Mooshroom")
|
||||||
mooshroom_def.mesh = "mobs_mc_cow.b3d"
|
mooshroom_def.mesh = "mobs_mc_cow.b3d"
|
||||||
|
mooshroom_def.spawn_in_group_min = 4
|
||||||
|
mooshroom_def.spawn_in_group = 8
|
||||||
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
|
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
|
||||||
mooshroom_def.on_rightclick = function(self, clicker)
|
mooshroom_def.on_rightclick = function(self, clicker)
|
||||||
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
|
@ -151,17 +153,12 @@ mcl_mobs:spawn_specific(
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"flat",
|
"flat",
|
||||||
"IcePlainsSpikes",
|
|
||||||
"ColdTaiga",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"MegaTaiga",
|
"MegaTaiga",
|
||||||
"MegaSpruceTaiga",
|
"MegaSpruceTaiga",
|
||||||
"ExtremeHills",
|
"ExtremeHills",
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"ExtremeHills+",
|
"ExtremeHills+",
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
"StoneBeach",
|
"StoneBeach",
|
||||||
"Plains",
|
"Plains",
|
||||||
"Plains_beach",
|
"Plains_beach",
|
||||||
|
|
|
@ -274,7 +274,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Plains",
|
"Plains",
|
||||||
"Desert",
|
"Desert",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -301,7 +300,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
@ -340,7 +338,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest_deep_ocean",
|
"Forest_deep_ocean",
|
||||||
"JungleM_deep_ocean",
|
"JungleM_deep_ocean",
|
||||||
"FlowerForest_deep_ocean",
|
"FlowerForest_deep_ocean",
|
||||||
"MushroomIsland_ocean",
|
|
||||||
"MegaTaiga_ocean",
|
"MegaTaiga_ocean",
|
||||||
"StoneBeach_deep_ocean",
|
"StoneBeach_deep_ocean",
|
||||||
"IcePlainsSpikes_deep_ocean",
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
@ -350,7 +347,6 @@ mcl_mobs:spawn_specific(
|
||||||
"MesaBryce_deep_ocean",
|
"MesaBryce_deep_ocean",
|
||||||
"ExtremeHills+_deep_ocean",
|
"ExtremeHills+_deep_ocean",
|
||||||
"ExtremeHills_ocean",
|
"ExtremeHills_ocean",
|
||||||
"MushroomIsland_deep_ocean",
|
|
||||||
"Forest_ocean",
|
"Forest_ocean",
|
||||||
"MegaTaiga_deep_ocean",
|
"MegaTaiga_deep_ocean",
|
||||||
"JungleEdge_ocean",
|
"JungleEdge_ocean",
|
||||||
|
@ -376,7 +372,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
|
|
@ -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,
|
physical = true,
|
||||||
damage = 10,
|
damage = 10,
|
||||||
|
knock_back = false,
|
||||||
jump = true,
|
jump = true,
|
||||||
jump_height = 14,
|
jump_height = 14,
|
||||||
fly = true,
|
fly = true,
|
||||||
|
|
|
@ -627,7 +627,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Plains",
|
"Plains",
|
||||||
"Desert",
|
"Desert",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -654,7 +653,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
@ -693,7 +691,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest_deep_ocean",
|
"Forest_deep_ocean",
|
||||||
"JungleM_deep_ocean",
|
"JungleM_deep_ocean",
|
||||||
"FlowerForest_deep_ocean",
|
"FlowerForest_deep_ocean",
|
||||||
"MushroomIsland_ocean",
|
|
||||||
"MegaTaiga_ocean",
|
"MegaTaiga_ocean",
|
||||||
"StoneBeach_deep_ocean",
|
"StoneBeach_deep_ocean",
|
||||||
"IcePlainsSpikes_deep_ocean",
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
@ -703,7 +700,6 @@ mcl_mobs:spawn_specific(
|
||||||
"MesaBryce_deep_ocean",
|
"MesaBryce_deep_ocean",
|
||||||
"ExtremeHills+_deep_ocean",
|
"ExtremeHills+_deep_ocean",
|
||||||
"ExtremeHills_ocean",
|
"ExtremeHills_ocean",
|
||||||
"MushroomIsland_deep_ocean",
|
|
||||||
"Forest_ocean",
|
"Forest_ocean",
|
||||||
"MegaTaiga_deep_ocean",
|
"MegaTaiga_deep_ocean",
|
||||||
"JungleEdge_ocean",
|
"JungleEdge_ocean",
|
||||||
|
@ -729,7 +725,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
@ -766,15 +761,32 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"SoulsandVall3ey",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
7,
|
11,
|
||||||
30,
|
30,
|
||||||
27500,
|
27500,
|
||||||
4,
|
4,
|
||||||
mcl_vars.mg_nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mcl_vars.mg_nether_max)
|
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
|
-- spawn eggs
|
||||||
mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)
|
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},
|
collisionbox = {-2, 5, -2, 2, 9, 2},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_ghast.b3d",
|
mesh = "mobs_mc_ghast.b3d",
|
||||||
|
spawn_in_group = 1,
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_mc_ghast.png"},
|
{"mobs_mc_ghast.png"},
|
||||||
},
|
},
|
||||||
|
@ -81,12 +82,14 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"SoulsandValley",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
7,
|
||||||
30,
|
30,
|
||||||
18000,
|
72000,
|
||||||
2,
|
2,
|
||||||
mcl_vars.mg_nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mcl_vars.mg_nether_max)
|
mcl_vars.mg_nether_max)
|
||||||
|
@ -105,7 +108,12 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = {fleshy = 6},
|
damage_groups = {fleshy = 6},
|
||||||
}, nil)
|
}, nil)
|
||||||
mcl_mobs:boom(self, self.object:get_pos(), 1, true)
|
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,
|
end,
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
hit_mob = function(self, mob)
|
||||||
|
|
|
@ -8,6 +8,8 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
|
||||||
description = S("Guardian"),
|
description = S("Guardian"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
spawn_in_group_min = 2,
|
||||||
|
spawn_in_group = 4,
|
||||||
hp_min = 30,
|
hp_min = 30,
|
||||||
hp_max = 30,
|
hp_max = 30,
|
||||||
xp_min = 10,
|
xp_min = 10,
|
||||||
|
|
|
@ -81,11 +81,27 @@ for b=1, #horse_base do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems
|
||||||
|
-- this results in existing horses wearing armor would still have the old texture filename in their
|
||||||
|
-- properties this function updates them. It should be removed some time in the future when we can be
|
||||||
|
-- reasonably sure all horses that want it get the new nexture.
|
||||||
|
local function update_textures(self)
|
||||||
|
local old = "mobs_mc_horse_armor_"
|
||||||
|
local txt = self.object:get_properties().textures
|
||||||
|
if txt[2]:find(old) then
|
||||||
|
txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_")
|
||||||
|
self.object:set_properties({textures=txt})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Horse
|
-- Horse
|
||||||
local horse = {
|
local horse = {
|
||||||
description = S("Horse"),
|
description = S("Horse"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
spawn_in_group_min = 2,
|
||||||
|
spawn_in_group = 6,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_horse.b3d",
|
mesh = "mobs_mc_horse.b3d",
|
||||||
visual_size = {x=3.0, y=3.0},
|
visual_size = {x=3.0, y=3.0},
|
||||||
|
@ -138,7 +154,7 @@ local horse = {
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
},
|
},
|
||||||
|
on_spawn = update_textures,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
-- set needed values if not already present
|
-- set needed values if not already present
|
||||||
|
@ -476,6 +492,8 @@ local d = 0.86 -- donkey scale
|
||||||
local donkey = table.copy(horse)
|
local donkey = table.copy(horse)
|
||||||
donkey.description = S("Donkey")
|
donkey.description = S("Donkey")
|
||||||
donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}}
|
donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}}
|
||||||
|
donkey.spawn_in_group = 3
|
||||||
|
donkey.spawn_in_group_min = 1
|
||||||
donkey.animation = {
|
donkey.animation = {
|
||||||
speed_normal = 25,
|
speed_normal = 25,
|
||||||
stand_start = 0, stand_end = 0,
|
stand_start = 0, stand_end = 0,
|
||||||
|
@ -528,41 +546,14 @@ mcl_mobs:spawn_specific(
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"flat",
|
"flat",
|
||||||
"IcePlainsSpikes",
|
|
||||||
"ColdTaiga",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"MegaTaiga",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ExtremeHillsM",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
"StoneBeach",
|
|
||||||
"Plains",
|
"Plains",
|
||||||
"Plains_beach",
|
"Plains_beach",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"Taiga",
|
|
||||||
"Taiga_beach",
|
|
||||||
"Forest",
|
|
||||||
"Forest_beach",
|
|
||||||
"FlowerForest",
|
|
||||||
"FlowerForest_beach",
|
|
||||||
"BirchForest",
|
|
||||||
"BirchForestM",
|
|
||||||
"RoofedForest",
|
|
||||||
"Savanna",
|
"Savanna",
|
||||||
"Savanna_beach",
|
"Savanna_beach",
|
||||||
"SavannaM",
|
"SavannaM",
|
||||||
"Jungle",
|
"Savanna_beach",
|
||||||
"Jungle_shore",
|
"Plains_beach",
|
||||||
"JungleM",
|
|
||||||
"JungleM_shore",
|
|
||||||
"JungleEdge",
|
|
||||||
"JungleEdgeM",
|
|
||||||
"Swampland",
|
|
||||||
"Swampland_shore"
|
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -572,20 +563,22 @@ minetest.LIGHT_MAX+1,
|
||||||
mobs_mc.water_level+3,
|
mobs_mc.water_level+3,
|
||||||
mcl_vars.mg_overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
|
||||||
mcl_mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:donkey",
|
"mobs_mc:donkey",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Mesa",
|
"flat",
|
||||||
"MesaPlateauFM_grasstop",
|
"Plains",
|
||||||
"MesaPlateauF",
|
"Plains_beach",
|
||||||
"MesaPlateauFM",
|
"SunflowerPlains",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna",
|
||||||
"MesaBryce",
|
"Savanna_beach",
|
||||||
|
"SavannaM",
|
||||||
|
"Savanna_beach",
|
||||||
|
"Plains_beach",
|
||||||
},
|
},
|
||||||
0,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
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 .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
|
||||||
dofile(path .. "/vex.lua") -- KrupnoPavel
|
dofile(path .. "/vex.lua") -- KrupnoPavel
|
||||||
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
||||||
|
|
||||||
|
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,
|
run_velocity = 1.2,
|
||||||
-- Approximation
|
-- Approximation
|
||||||
damage = 14,
|
damage = 14,
|
||||||
|
knock_back = false,
|
||||||
reach = 3,
|
reach = 3,
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
attacks_monsters = true,
|
attacks_monsters = true,
|
||||||
|
|
|
@ -28,6 +28,8 @@ mcl_mobs:register_mob("mobs_mc:llama", {
|
||||||
description = S("Llama"),
|
description = S("Llama"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
spawn_in_group_min = 4,
|
||||||
|
spawn_in_group = 6,
|
||||||
hp_min = 15,
|
hp_min = 15,
|
||||||
hp_max = 30,
|
hp_max = 30,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -217,18 +219,16 @@ mcl_mobs:spawn_specific(
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Mesa",
|
"Savanna",
|
||||||
"MesaPlateauFM_grasstop",
|
"SavannaM",
|
||||||
"MesaPlateauF",
|
"SavannaM_beach",
|
||||||
"MesaPlateauFM",
|
"Savanna_beach",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna_ocean",
|
||||||
"MesaBryce",
|
|
||||||
"Jungle",
|
|
||||||
"Jungle_shore",
|
|
||||||
"JungleM",
|
|
||||||
"JungleM_shore",
|
|
||||||
"JungleEdge",
|
"JungleEdge",
|
||||||
"JungleEdgeM",
|
"JungleEdgeM",
|
||||||
|
"ExtremeHills",
|
||||||
|
"ExtremeHills_beach",
|
||||||
|
"ExtremeHillsM",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
|
|
@ -1,64 +1,58 @@
|
||||||
# textdomain: mobs_mc
|
# textdomain: mobs_mc
|
||||||
Agent=Agente
|
|
||||||
Bat=Murciélago
|
Bat=Murciélago
|
||||||
Blaze=Blaze
|
Blaze=Blaze
|
||||||
Chicken=Pollo
|
Chicken=Pollo
|
||||||
|
Cod=Bacalao
|
||||||
Cow=Vaca
|
Cow=Vaca
|
||||||
Mooshroom=Champiñaca
|
Mooshroom=Champivaca
|
||||||
Creeper=Creeper
|
Creeper=Creeper
|
||||||
Ender Dragon=Enderdragón
|
Dolphin=Delfín
|
||||||
|
Ender Dragon=Ender Dragon
|
||||||
Enderman=Enderman
|
Enderman=Enderman
|
||||||
Endermite=Endermite
|
Endermite=Endermite
|
||||||
Ghast=Ghast
|
Ghast=Ghast
|
||||||
Elder Guardian=Gran guardián
|
|
||||||
Guardian=Guardián
|
Guardian=Guardián
|
||||||
Horse=Caballo
|
Elder Guardian=Guardián Anciano
|
||||||
Skeleton Horse=Caballo esquelético
|
|
||||||
Zombie Horse=Caballo zombie
|
|
||||||
Donkey=Burro
|
Donkey=Burro
|
||||||
|
Horse=Caballo
|
||||||
Mule=Mula
|
Mule=Mula
|
||||||
|
Skeleton Horse=Caballo esqueleto
|
||||||
|
Zombie Horse=Caballo zombi
|
||||||
Iron Golem=Golem de hierro
|
Iron Golem=Golem de hierro
|
||||||
Llama=Llama
|
Llama=Llama
|
||||||
|
Cat=Gato
|
||||||
Ocelot=Ocelote
|
Ocelot=Ocelote
|
||||||
Parrot=Loro
|
Parrot=Loro
|
||||||
Pig=Cerdo
|
Pig=Cerdo
|
||||||
Polar Bear=Oso polar
|
Polar Bear=Oso polar
|
||||||
Rabbit=Conejo
|
|
||||||
Killer Bunny=Conejo asesino
|
Killer Bunny=Conejo asesino
|
||||||
|
Rabbit=Conejo
|
||||||
|
Salmon=Salmón
|
||||||
Sheep=Oveja
|
Sheep=Oveja
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Lepisma
|
Silverfish=Lepisma
|
||||||
Skeleton=Esqueleto
|
Skeleton=Esqueleto
|
||||||
Stray=Esqueleto
|
Stray=Esqueleto glacial
|
||||||
Wither Skeleton=Esqueleto wither
|
Wither Skeleton=Esqueleto del Wither
|
||||||
Magma Cube=Cubo de Magma
|
Magma Cube=Cubo de Magma
|
||||||
Slime=Slime
|
Slime=Slime
|
||||||
Snow Golem=Golem de nieve
|
Snow Golem=Golem de nieve
|
||||||
Spider=Araña
|
|
||||||
Cave Spider=Araña de las cuevas
|
Cave Spider=Araña de las cuevas
|
||||||
|
Spider=Araña
|
||||||
Squid=Calamar
|
Squid=Calamar
|
||||||
Vex=Ánima
|
Vex=Ánima
|
||||||
|
Master=Maestro
|
||||||
|
Villager=Aldeano
|
||||||
Evoker=Invocador
|
Evoker=Invocador
|
||||||
Illusioner=Illusionista
|
Illusioner=Illusionista
|
||||||
Villager=Aldeano
|
|
||||||
Vindicator=Vindicador
|
Vindicator=Vindicador
|
||||||
Zombie Villager=Aldeano zombie
|
Zombie Villager=Aldeano zombi
|
||||||
Witch=Bruja
|
Witch=Bruja
|
||||||
Wither=Wither
|
Wither=Wither
|
||||||
Wolf=Lobo
|
Wolf=Lobo
|
||||||
Husk=Husk
|
Baby Husk=Bebé Zombi Momificado
|
||||||
Zombie=Zombie
|
Baby Zombie=Bebé Zombi
|
||||||
Zombie Pigman=Cerdo Zombie
|
Husk=Zombi Momificado
|
||||||
Farmer=Granjero
|
Zombie=Zombi
|
||||||
Fisherman=Pescador
|
Baby Zombie Pigman=Bebé Hombrecerdo Zombi
|
||||||
Fletcher=Flechador
|
Zombie Pigman=Hombrecerdo Zombi
|
||||||
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
|
|
||||||
|
|
|
@ -62,3 +62,6 @@ Weapon Smith=
|
||||||
Tool Smith=
|
Tool Smith=
|
||||||
Cleric=
|
Cleric=
|
||||||
Nitwit=
|
Nitwit=
|
||||||
|
Cod=
|
||||||
|
Salmon=
|
||||||
|
Dolphin=
|
||||||
|
|
|
@ -30,6 +30,8 @@ local ocelot = {
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
can_despawn = true,
|
can_despawn = true,
|
||||||
|
spawn_in_group = 3,
|
||||||
|
spawn_in_group_min = 1,
|
||||||
hp_min = 10,
|
hp_min = 10,
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
|
|
@ -13,6 +13,45 @@ local shoulders = {
|
||||||
right = 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
|
--find a free shoulder or return nil
|
||||||
local function get_shoulder(player)
|
local function get_shoulder(player)
|
||||||
local sh = "left"
|
local sh = "left"
|
||||||
|
@ -159,6 +198,7 @@ mcl_mobs:register_mob("mobs_mc:parrot", {
|
||||||
end,
|
end,
|
||||||
do_custom = function(self,dtime)
|
do_custom = function(self,dtime)
|
||||||
check_perch(self,dtime)
|
check_perch(self,dtime)
|
||||||
|
check_mobimitate(self,dtime)
|
||||||
end,
|
end,
|
||||||
do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later....
|
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
|
if self.object:get_attach() == puncher then
|
||||||
|
|
|
@ -194,17 +194,12 @@ mcl_mobs:spawn_specific(
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"flat",
|
"flat",
|
||||||
"IcePlainsSpikes",
|
|
||||||
"ColdTaiga",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"MegaTaiga",
|
"MegaTaiga",
|
||||||
"MegaSpruceTaiga",
|
"MegaSpruceTaiga",
|
||||||
"ExtremeHills",
|
"ExtremeHills",
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"ExtremeHills+",
|
"ExtremeHills+",
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
"StoneBeach",
|
"StoneBeach",
|
||||||
"Plains",
|
"Plains",
|
||||||
"Plains_beach",
|
"Plains_beach",
|
||||||
|
|
|
@ -76,7 +76,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
|
|
@ -6,9 +6,10 @@ local rabbit = {
|
||||||
description = S("Rabbit"),
|
description = S("Rabbit"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
spawn_in_group_min = 2,
|
||||||
|
spawn_in_group = 3,
|
||||||
passive = true,
|
passive = true,
|
||||||
reach = 1,
|
reach = 1,
|
||||||
|
|
||||||
hp_min = 3,
|
hp_min = 3,
|
||||||
hp_max = 3,
|
hp_max = 3,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -132,18 +133,9 @@ mcl_mobs:spawn_specific(
|
||||||
"Desert",
|
"Desert",
|
||||||
"FlowerForest",
|
"FlowerForest",
|
||||||
"Taiga",
|
"Taiga",
|
||||||
"ExtremeHills",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
"MegaSpruceTaiga",
|
||||||
"MegaTaiga",
|
"MegaTaiga",
|
||||||
"ExtremeHills+",
|
|
||||||
"Plains",
|
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"SunflowerPlains",
|
|
||||||
"RoofedForest",
|
|
||||||
"MesaPlateauFM_grasstop",
|
|
||||||
"ExtremeHillsM",
|
|
||||||
"BirchForestM",
|
|
||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
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)
|
|
@ -346,7 +346,7 @@ mcl_mobs:spawn_specific(
|
||||||
"Swampland",
|
"Swampland",
|
||||||
"Swampland_shore"
|
"Swampland_shore"
|
||||||
},
|
},
|
||||||
0,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
|
|
|
@ -33,6 +33,7 @@ mcl_mobs:register_mob("mobs_mc:shulker", {
|
||||||
-- TODO: Make shulker dye-able
|
-- TODO: Make shulker dye-able
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
walk_chance = 0,
|
walk_chance = 0,
|
||||||
|
knock_back = false,
|
||||||
jump = false,
|
jump = false,
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mcl_mobitems:shulker_shell",
|
{name = "mcl_mobitems:shulker_shell",
|
||||||
|
|
|
@ -162,7 +162,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Plains",
|
"Plains",
|
||||||
"Desert",
|
"Desert",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -189,7 +188,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
@ -228,7 +226,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest_deep_ocean",
|
"Forest_deep_ocean",
|
||||||
"JungleM_deep_ocean",
|
"JungleM_deep_ocean",
|
||||||
"FlowerForest_deep_ocean",
|
"FlowerForest_deep_ocean",
|
||||||
"MushroomIsland_ocean",
|
|
||||||
"MegaTaiga_ocean",
|
"MegaTaiga_ocean",
|
||||||
"StoneBeach_deep_ocean",
|
"StoneBeach_deep_ocean",
|
||||||
"IcePlainsSpikes_deep_ocean",
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
@ -238,7 +235,6 @@ mcl_mobs:spawn_specific(
|
||||||
"MesaBryce_deep_ocean",
|
"MesaBryce_deep_ocean",
|
||||||
"ExtremeHills+_deep_ocean",
|
"ExtremeHills+_deep_ocean",
|
||||||
"ExtremeHills_ocean",
|
"ExtremeHills_ocean",
|
||||||
"MushroomIsland_deep_ocean",
|
|
||||||
"Forest_ocean",
|
"Forest_ocean",
|
||||||
"MegaTaiga_deep_ocean",
|
"MegaTaiga_deep_ocean",
|
||||||
"JungleEdge_ocean",
|
"JungleEdge_ocean",
|
||||||
|
@ -264,7 +260,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
@ -302,10 +297,10 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"SoulsandValley",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
7,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
10000,
|
10000,
|
||||||
3,
|
3,
|
||||||
|
|
|
@ -101,7 +101,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"SoulsandValley",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
7,
|
7,
|
||||||
|
|
|
@ -402,7 +402,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -418,7 +419,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -433,7 +435,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -443,11 +446,6 @@ minetest.LIGHT_MAX+1,
|
||||||
mmin,
|
mmin,
|
||||||
mmax)
|
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
|
-- 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: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")
|
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",
|
"Plains",
|
||||||
"Desert",
|
"Desert",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -136,7 +135,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
@ -175,7 +173,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest_deep_ocean",
|
"Forest_deep_ocean",
|
||||||
"JungleM_deep_ocean",
|
"JungleM_deep_ocean",
|
||||||
"FlowerForest_deep_ocean",
|
"FlowerForest_deep_ocean",
|
||||||
"MushroomIsland_ocean",
|
|
||||||
"MegaTaiga_ocean",
|
"MegaTaiga_ocean",
|
||||||
"StoneBeach_deep_ocean",
|
"StoneBeach_deep_ocean",
|
||||||
"IcePlainsSpikes_deep_ocean",
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
@ -185,7 +182,6 @@ mcl_mobs:spawn_specific(
|
||||||
"MesaBryce_deep_ocean",
|
"MesaBryce_deep_ocean",
|
||||||
"ExtremeHills+_deep_ocean",
|
"ExtremeHills+_deep_ocean",
|
||||||
"ExtremeHills_ocean",
|
"ExtremeHills_ocean",
|
||||||
"MushroomIsland_deep_ocean",
|
|
||||||
"Forest_ocean",
|
"Forest_ocean",
|
||||||
"MegaTaiga_deep_ocean",
|
"MegaTaiga_deep_ocean",
|
||||||
"JungleEdge_ocean",
|
"JungleEdge_ocean",
|
||||||
|
@ -211,7 +207,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
|
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 |
|
@ -136,8 +136,7 @@ local professions = {
|
||||||
{
|
{
|
||||||
{ { "mcl_fishing:fish_raw", 6, 15,}, E1 },
|
{ { "mcl_fishing:fish_raw", 6, 15,}, E1 },
|
||||||
{ { "mcl_fishing:salmon_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:salmon_cooked", 6, 6 } },
|
{ { "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_lit",1,1} },
|
||||||
-- {{ "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire",1,1} },
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ { "mcl_fishing:salmon_raw", 6, 13,}, E1 },
|
{ { "mcl_fishing:salmon_raw", 6, 13,}, E1 },
|
||||||
|
@ -427,7 +426,7 @@ local professions = {
|
||||||
"mobs_mc_villager_weaponsmith.png",
|
"mobs_mc_villager_weaponsmith.png",
|
||||||
"mobs_mc_villager_weaponsmith.png",
|
"mobs_mc_villager_weaponsmith.png",
|
||||||
},
|
},
|
||||||
jobsite = "mcl_furnaces:furnace", --FIXME: grindstone
|
jobsite = "mcl_grindstone:grindstone",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
|
@ -458,7 +457,7 @@ local professions = {
|
||||||
"mobs_mc_villager_toolsmith.png",
|
"mobs_mc_villager_toolsmith.png",
|
||||||
"mobs_mc_villager_toolsmith.png",
|
"mobs_mc_villager_toolsmith.png",
|
||||||
},
|
},
|
||||||
jobsite = "mcl_anvils:anvil", --FIXME: smithing table
|
jobsite = "mcl_smithing_table:table",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
|
@ -613,6 +612,8 @@ local function employ(self,jobsite_pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function look_for_job(self)
|
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 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)
|
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
|
for _,n in pairs(nn) do
|
||||||
|
@ -628,14 +629,24 @@ local function look_for_job(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_a_job(self)
|
local function get_a_job(self)
|
||||||
|
if self.child then return end
|
||||||
local p = self.object:get_pos()
|
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)
|
local n = minetest.find_node_near(p,1,jobsites)
|
||||||
for _,n in pairs(nn) do
|
|
||||||
if n and employ(self,n) then return true end
|
if n and employ(self,n) then return true end
|
||||||
end
|
|
||||||
if self.state ~= "gowp" then look_for_job(self) end
|
if self.state ~= "gowp" then look_for_job(self) end
|
||||||
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)
|
local function update_max_tradenum(self)
|
||||||
if not self._trades then
|
if not self._trades then
|
||||||
return
|
return
|
||||||
|
@ -724,7 +735,10 @@ local function set_trade(trader, player, inv, concrete_tradenum)
|
||||||
local trade = trades[concrete_tradenum]
|
local trade = trades[concrete_tradenum]
|
||||||
inv:set_stack("wanted", 1, ItemStack(trade.wanted[1]))
|
inv:set_stack("wanted", 1, ItemStack(trade.wanted[1]))
|
||||||
local offered = ItemStack(trade.offered)
|
local offered = ItemStack(trade.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)
|
mcl_enchanting.load_enchantments(offered)
|
||||||
|
end
|
||||||
inv:set_stack("offered", 1, offered)
|
inv:set_stack("offered", 1, offered)
|
||||||
if trade.wanted[2] then
|
if trade.wanted[2] then
|
||||||
local wanted2 = ItemStack(trade.wanted[2])
|
local wanted2 = ItemStack(trade.wanted[2])
|
||||||
|
@ -982,6 +996,11 @@ local trade_inventory = {
|
||||||
elseif listname == "output" then
|
elseif listname == "output" then
|
||||||
if not trader_exists(player:get_player_name()) then
|
if not trader_exists(player:get_player_name()) then
|
||||||
return 0
|
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
|
end
|
||||||
-- Only allow taking full stack
|
-- Only allow taking full stack
|
||||||
local count = stack:get_count()
|
local count = stack:get_count()
|
||||||
|
@ -1094,6 +1113,7 @@ local trade_inventory = {
|
||||||
local trader = player_trading_with[name]
|
local trader = player_trading_with[name]
|
||||||
local tradenum = player_tradenum[name]
|
local tradenum = player_tradenum[name]
|
||||||
local trades
|
local trades
|
||||||
|
trader._traded = true
|
||||||
if trader and trader._trades then
|
if trader and trader._trades then
|
||||||
trades = minetest.deserialize(trader._trades)
|
trades = minetest.deserialize(trader._trades)
|
||||||
end
|
end
|
||||||
|
@ -1224,6 +1244,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
||||||
-- TODO: sounds
|
-- TODO: sounds
|
||||||
sounds = {
|
sounds = {
|
||||||
random = "mobs_mc_villager",
|
random = "mobs_mc_villager",
|
||||||
|
damage = "mobs_mc_villager_hurt",
|
||||||
distance = 10,
|
distance = 10,
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
|
@ -1236,10 +1257,12 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
||||||
run_speed = 25,
|
run_speed = 25,
|
||||||
run_start = 0,
|
run_start = 0,
|
||||||
run_end = 40,
|
run_end = 40,
|
||||||
die_speed = 15,
|
head_shake_start = 210,
|
||||||
die_start = 210,
|
head_shake_end = 220,
|
||||||
die_end = 220,
|
head_shake_loop = false,
|
||||||
die_loop = false,
|
head_nod_start = 210,
|
||||||
|
head_nod_end = 220,
|
||||||
|
head_nod_loop = false,
|
||||||
},
|
},
|
||||||
follow = pick_up,
|
follow = pick_up,
|
||||||
nofollow = true,
|
nofollow = true,
|
||||||
|
@ -1261,19 +1284,18 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if clicker then
|
if clicker then
|
||||||
mcl_mobs:feed_tame(self, clicker, 1, true, false)
|
mcl_mobs:feed_tame(self, clicker, 1, true, false, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
return true --do not pick up
|
return true --do not pick up
|
||||||
end,
|
end,
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
local trg=vector.new(0,9,0)
|
|
||||||
if self._jobsite then
|
if self._jobsite then
|
||||||
mcl_mobs:gopath(self,self._jobsite,function()
|
mcl_mobs:gopath(self,self._jobsite,function()
|
||||||
--minetest.log("arrived at jobsite")
|
--minetest.log("arrived at jobsite")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
if self.child or self._profession == "unemployed" then
|
if self.child or self._profession == "unemployed" or self._profession == "nitwit" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- Initiate trading
|
-- Initiate trading
|
||||||
|
@ -1344,20 +1366,24 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
||||||
end
|
end
|
||||||
if self._profession == "unemployed" then
|
if self._profession == "unemployed" then
|
||||||
get_a_job(self)
|
get_a_job(self)
|
||||||
|
else
|
||||||
|
check_jobsite(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_spawn = function(self)
|
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
|
if self._id then
|
||||||
set_textures(self)
|
set_textures(self)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random()))
|
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)
|
set_textures(self)
|
||||||
end,
|
end,
|
||||||
on_die = function(self, pos)
|
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(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:villager",
|
"mobs_mc:villager",
|
||||||
"overworld",
|
"overworld",
|
||||||
|
@ -1406,6 +1433,6 @@ minetest.LIGHT_MAX+1,
|
||||||
4,
|
4,
|
||||||
mobs_mc.water_level+1,
|
mobs_mc.water_level+1,
|
||||||
mcl_vars.mg_overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
--]]
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mcl_mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0)
|
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"),
|
description = S("Zombie Villager"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
spawn_in_group = 1,
|
||||||
hp_min = 20,
|
hp_min = 20,
|
||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
xp_min = 5,
|
xp_min = 5,
|
||||||
|
@ -119,20 +120,7 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", {
|
||||||
villager_obj:set_yaw(yaw)
|
villager_obj:set_yaw(yaw)
|
||||||
villager.target_yaw = yaw
|
villager.target_yaw = yaw
|
||||||
villager.nametag = self.nametag
|
villager.nametag = self.nametag
|
||||||
local texture = self.base_texture[1]:gsub("zombie", "villager")
|
villager._profession = "unemployed"
|
||||||
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)]
|
|
||||||
self._curing = nil
|
self._curing = nil
|
||||||
mcl_burning.extinguish(obj)
|
mcl_burning.extinguish(obj)
|
||||||
obj:remove()
|
obj:remove()
|
||||||
|
@ -160,7 +148,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
@ -197,7 +184,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Plains",
|
"Plains",
|
||||||
"Desert",
|
"Desert",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -224,7 +210,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
|
|
@ -18,6 +18,7 @@ local wolf = {
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
passive = false,
|
passive = false,
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
|
spawn_in_group = 8,
|
||||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_wolf.b3d",
|
mesh = "mobs_mc_wolf.b3d",
|
||||||
|
@ -232,29 +233,22 @@ dog.on_rightclick = function(self, clicker)
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_mobs:register_mob("mobs_mc:dog", dog)
|
mcl_mobs:register_mob("mobs_mc:dog", dog)
|
||||||
|
|
||||||
-- Spawn
|
-- Spawn
|
||||||
mcl_mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:wolf",
|
"mobs_mc:wolf",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
"Taiga",
|
||||||
"ExtremeHills",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
"MegaSpruceTaiga",
|
||||||
"MegaTaiga",
|
"MegaTaiga",
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
"Forest",
|
||||||
"Plains",
|
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"SunflowerPlains",
|
"FlowerForest_beach",
|
||||||
"RoofedForest",
|
"Forest_beach",
|
||||||
"MesaPlateauFM_grasstop",
|
"ColdTaiga_beach_water",
|
||||||
"ExtremeHillsM",
|
"Taiga_beach",
|
||||||
"BirchForestM",
|
"ColdTaiga_beach",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
|
|
@ -162,7 +162,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
@ -198,7 +197,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest",
|
"Forest",
|
||||||
"Plains",
|
"Plains",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -225,7 +223,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
@ -254,7 +251,6 @@ mcl_mobs:spawn_specific(
|
||||||
"RoofedForest_underground",
|
"RoofedForest_underground",
|
||||||
"Jungle_underground",
|
"Jungle_underground",
|
||||||
"Swampland_underground",
|
"Swampland_underground",
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
"BirchForest_underground",
|
||||||
"Plains_underground",
|
"Plains_underground",
|
||||||
"MesaPlateauF_underground",
|
"MesaPlateauF_underground",
|
||||||
|
@ -290,7 +286,6 @@ mcl_mobs:spawn_specific(
|
||||||
"Forest",
|
"Forest",
|
||||||
"Plains",
|
"Plains",
|
||||||
"ColdTaiga",
|
"ColdTaiga",
|
||||||
"MushroomIsland",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"SunflowerPlains",
|
||||||
"IcePlains",
|
"IcePlains",
|
||||||
|
@ -317,7 +312,6 @@ mcl_mobs:spawn_specific(
|
||||||
"ExtremeHills_beach",
|
"ExtremeHills_beach",
|
||||||
"ColdTaiga_beach",
|
"ColdTaiga_beach",
|
||||||
"Swampland_shore",
|
"Swampland_shore",
|
||||||
"MushroomIslandShore",
|
|
||||||
"JungleM_shore",
|
"JungleM_shore",
|
||||||
"Jungle_shore",
|
"Jungle_shore",
|
||||||
"MesaPlateauFM_sandlevel",
|
"MesaPlateauFM_sandlevel",
|
||||||
|
|
|
@ -118,7 +118,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"CrimsonForest",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -133,7 +134,8 @@ mcl_mobs:spawn_specific(
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"CrimsonForest",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
|
|
@ -238,8 +238,8 @@ after(5, function(dtime)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_chatcommand("lightning", {
|
minetest.register_chatcommand("lightning", {
|
||||||
params = "[<X> <Y> <Z>]",
|
params = "[<X> <Y> <Z> | <player name>]",
|
||||||
description = S("Let lightning strike at the specified position or yourself"),
|
description = S("Let lightning strike at the specified position or player. No parameter will strike yourself."),
|
||||||
privs = { maphack = true },
|
privs = { maphack = true },
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local pos = {}
|
local pos = {}
|
||||||
|
@ -247,21 +247,21 @@ minetest.register_chatcommand("lightning", {
|
||||||
pos.x = tonumber(pos.x)
|
pos.x = tonumber(pos.x)
|
||||||
pos.y = tonumber(pos.y)
|
pos.y = tonumber(pos.y)
|
||||||
pos.z = tonumber(pos.z)
|
pos.z = tonumber(pos.z)
|
||||||
|
local player_to_strike
|
||||||
if not (pos.x and pos.y and pos.z) then
|
if not (pos.x and pos.y and pos.z) then
|
||||||
pos = nil
|
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
|
end
|
||||||
|
if not player_to_strike and pos == nil then
|
||||||
return false, "No position specified and unknown player"
|
return false, "No position specified and unknown player"
|
||||||
end
|
end
|
||||||
if pos then
|
if pos then
|
||||||
lightning.strike(pos)
|
lightning.strike(pos)
|
||||||
else
|
elseif player_to_strike then
|
||||||
local player = minetest.get_player_by_name(name)
|
lightning.strike(player_to_strike:get_pos())
|
||||||
if player then
|
|
||||||
lightning.strike(player:get_pos())
|
|
||||||
else
|
|
||||||
return false, S("No position specified and unknown player")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# textdomain: lightning
|
# textdomain: lightning
|
||||||
@1 was struck by lightning.=
|
Let lightning strike at the specified position or player. No parameter will strike yourself.=
|
||||||
Let lightning strike at the specified position or yourself=
|
|
||||||
No position specified and unknown player=
|
No position specified and unknown player=
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
mcl_weather.nether_dust = {}
|
mcl_weather.nether_dust = {}
|
||||||
mcl_weather.nether_dust.particlespawners = {}
|
mcl_weather.nether_dust.particlespawners = {}
|
||||||
|
|
||||||
|
local PARTICLES_COUNT_NETHER_DUST = tonumber(minetest.settings:get("mcl_weather_dust_particles")) or 150
|
||||||
|
|
||||||
local psdef= {
|
local psdef= {
|
||||||
amount = 150,
|
amount = PARTICLES_COUNT_NETHER_DUST,
|
||||||
time = 0,
|
time = 0,
|
||||||
minpos = vector.new(-15,-15,-15),
|
minpos = vector.new(-15,-15,-15),
|
||||||
maxpos =vector.new(15,15,15),
|
maxpos =vector.new(15,15,15),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
local PARTICLES_COUNT_RAIN = 800
|
local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_particles")) or 500
|
||||||
local PARTICLES_COUNT_THUNDER = 1200
|
local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900
|
||||||
|
|
||||||
local get_connected_players = minetest.get_connected_players
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
|
@ -20,22 +20,20 @@ mcl_weather.rain = {
|
||||||
init_done = false,
|
init_done = false,
|
||||||
}
|
}
|
||||||
local update_sound={}
|
local update_sound={}
|
||||||
local vel=math.random(0,3)
|
|
||||||
local falling_speed=math.random(10,15)
|
|
||||||
local size = math.random(1,3)
|
|
||||||
local psdef= {
|
local psdef= {
|
||||||
amount = mcl_weather.rain.particles_count,
|
amount = mcl_weather.rain.particles_count,
|
||||||
time=0,
|
time=0,
|
||||||
minpos = vector.new(-15,20,-15),
|
minpos = vector.new(-15,20,-15),
|
||||||
maxpos = vector.new(15,25,15),
|
maxpos = vector.new(15,25,15),
|
||||||
minvel = vector.new(-2,-falling_speed-2,-2),
|
minvel = vector.new(-2,-17,-2),
|
||||||
maxvel = vector.new(2,-falling_speed+2,2),
|
maxvel = vector.new(2,-8,2),
|
||||||
minacc = vector.new(0,0,0),
|
minacc = vector.new(0,0,0),
|
||||||
maxacc = vector.new(0,-0.5,0),
|
maxacc = vector.new(0,-0.5,0),
|
||||||
minexptime = 15,
|
minexptime = 1,
|
||||||
maxexptime = 30,
|
maxexptime = 4,
|
||||||
minsize = size,
|
minsize = 4,
|
||||||
maxsize= size*2,
|
maxsize= 8,
|
||||||
collisiondetection = true,
|
collisiondetection = true,
|
||||||
collision_removal = true,
|
collision_removal = true,
|
||||||
vertical = true,
|
vertical = true,
|
||||||
|
@ -70,9 +68,10 @@ end
|
||||||
-- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net.
|
-- 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)
|
function mcl_weather.rain.add_rain_particles(player)
|
||||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count
|
mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count
|
||||||
|
local l = false
|
||||||
for k,v in pairs(textures) do
|
for k,v in pairs(textures) do
|
||||||
psdef.texture=v
|
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
|
end
|
||||||
if l then
|
if l then
|
||||||
update_sound[player:get_player_name()]=true
|
update_sound[player:get_player_name()]=true
|
||||||
|
|
|
@ -146,8 +146,25 @@ mcl_weather.skycolor = {
|
||||||
player:set_stars({visible = false})
|
player:set_stars({visible = false})
|
||||||
mcl_weather.skycolor.override_day_night_ratio(player, 0.5)
|
mcl_weather.skycolor.override_day_night_ratio(player, 0.5)
|
||||||
elseif dim == "nether" then
|
elseif dim == "nether" then
|
||||||
player:set_sky({ type = "plain",
|
local nether_sky = {
|
||||||
base_color = "#300808",
|
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,
|
clouds = false,
|
||||||
})
|
})
|
||||||
player:set_sun({visible = false , sunrise_visible = false})
|
player:set_sun({visible = false , sunrise_visible = false})
|
||||||
|
|
|
@ -2,11 +2,11 @@ local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
mcl_weather.snow = {}
|
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
|
mcl_weather.snow.init_done = false
|
||||||
|
|
||||||
local psdef= {
|
local psdef= {
|
||||||
amount = 99,
|
amount = PARTICLES_COUNT_SNOW,
|
||||||
time = 0, --stay on til we turn it off
|
time = 0, --stay on til we turn it off
|
||||||
minpos = vector.new(-25,20,-25),
|
minpos = vector.new(-25,20,-25),
|
||||||
maxpos =vector.new(25,25,25),
|
maxpos =vector.new(25,25,25),
|
||||||
|
@ -14,9 +14,9 @@ local psdef= {
|
||||||
maxvel = vector.new(0.2,-4,0.2),
|
maxvel = vector.new(0.2,-4,0.2),
|
||||||
minacc = vector.new(0,-1,0),
|
minacc = vector.new(0,-1,0),
|
||||||
maxacc = vector.new(0,-4,0),
|
maxacc = vector.new(0,-4,0),
|
||||||
minexptime = 15,
|
minexptime = 3,
|
||||||
maxexptime = 30,
|
maxexptime = 5,
|
||||||
minsize = 0.5,
|
minsize = 2,
|
||||||
maxsize = 5,
|
maxsize = 5,
|
||||||
collisiondetection = true,
|
collisiondetection = true,
|
||||||
collision_removal = true,
|
collision_removal = true,
|
||||||
|
|
|
@ -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.
|
-- Item pickup achievements: These are awarded when picking up a certain item.
|
||||||
-- The achivements are manually given in the mod mcl_item_entity.
|
-- The achivements are manually given in the mod mcl_item_entity.
|
||||||
awards.register_achievement("mcl:diamonds", {
|
awards.register_achievement("mcl:diamonds", {
|
||||||
|
@ -125,6 +136,18 @@ awards.register_achievement("mcl:mineWood", {
|
||||||
icon = "default_tree.png",
|
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
|
-- Smelting achivements: These are awarded when picking up an item from a furnace
|
||||||
-- output. They are given in mcl_furnaces.
|
-- output. They are given in mcl_furnaces.
|
||||||
awards.register_achievement("mcl:acquireIron", {
|
awards.register_achievement("mcl:acquireIron", {
|
||||||
|
@ -158,9 +181,89 @@ awards.register_achievement("mcl:snipeSkeleton", {
|
||||||
|
|
||||||
-- Triggered in mcl_portals
|
-- Triggered in mcl_portals
|
||||||
awards.register_achievement("mcl:buildNetherPortal", {
|
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."),
|
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.)
|
-- 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.=
|
Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=
|
||||||
Hot Topic=
|
Hot Topic=
|
||||||
Into Fire=
|
Into Fire=
|
||||||
Into the Nether=
|
We Need to Go Deeper=
|
||||||
Iron Belly=
|
Iron Belly=
|
||||||
Librarian=
|
Librarian=
|
||||||
Mine emerald ore.=
|
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 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 obsidian and a fire starter to construct a Nether portal.=
|
||||||
Use wheat to craft a bread.=
|
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.=
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
## mcl_info
|
||||||
|
An api to make custom entries in the mcl2 debug hud.
|
||||||
|
|
||||||
|
### mcl_info.register_debug_field(name,defintion)
|
||||||
|
Debug field defintion example:
|
||||||
|
{
|
||||||
|
level = 3,
|
||||||
|
--show with debug level 3 and upwards
|
||||||
|
|
||||||
|
func = function(player,pos) return minetest.pos_to_string(pos) end,
|
||||||
|
-- Function that is run for at each debug
|
||||||
|
-- sample (default: every .63 seconds)
|
||||||
|
-- It should output a string and determines
|
||||||
|
-- the content of the debug field.
|
||||||
|
}
|
||||||
|
|
||||||
|
### mcl_info.registered_debug_fields
|
||||||
|
Table the debug definitions are stored in. Do not modify this directly. If you need to overwrite a field just set it again with mcl_info.register_debug_field().
|
|
@ -0,0 +1,161 @@
|
||||||
|
mcl_info = {}
|
||||||
|
local refresh_interval = .63
|
||||||
|
local huds = {}
|
||||||
|
local default_debug = 0
|
||||||
|
local after = minetest.after
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local get_biome_name = minetest.get_biome_name
|
||||||
|
local get_biome_data = minetest.get_biome_data
|
||||||
|
local format = string.format
|
||||||
|
|
||||||
|
local min1, min2, min3 = mcl_vars.mg_overworld_min, mcl_vars.mg_end_min, mcl_vars.mg_nether_min
|
||||||
|
local max1, max2, max3 = mcl_vars.mg_overworld_max, mcl_vars.mg_end_max, mcl_vars.mg_nether_max + 128
|
||||||
|
|
||||||
|
local modname = minetest.get_current_modname()
|
||||||
|
local modpath = minetest.get_modpath(modname)
|
||||||
|
local S = minetest.get_translator(modname)
|
||||||
|
local storage = minetest.get_mod_storage()
|
||||||
|
local player_dbg = {}
|
||||||
|
|
||||||
|
local function check_setting(s)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
--return player setting, set it to 2nd argument if supplied
|
||||||
|
local function player_setting(p,s)
|
||||||
|
local name = p:get_player_name()
|
||||||
|
if check_setting(s) then
|
||||||
|
p:get_meta():set_string("mcl_info_show",s)
|
||||||
|
player_dbg[name] = tonumber(s)
|
||||||
|
end
|
||||||
|
if not player_dbg[name] then
|
||||||
|
local r = p:get_meta():get_string("mcl_info_show")
|
||||||
|
if r == nil or r == "" then r = 0 end
|
||||||
|
player_dbg[name] = tonumber(r)
|
||||||
|
end
|
||||||
|
return player_dbg[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_info.registered_debug_fields = {}
|
||||||
|
local fields_keyset = {}
|
||||||
|
function mcl_info.register_debug_field(name,def)
|
||||||
|
table.insert(fields_keyset,name)
|
||||||
|
mcl_info.registered_debug_fields[name]=def
|
||||||
|
end
|
||||||
|
|
||||||
|
local function nodeinfo(pos)
|
||||||
|
local n = minetest.get_node_or_nil(pos)
|
||||||
|
if not n then return "" end
|
||||||
|
local l = minetest.get_node_light(pos)
|
||||||
|
local ld = minetest.get_node_light(pos,0.5)
|
||||||
|
local r = n.name .. " p1:"..n.param1.." p2:"..n.param2
|
||||||
|
if l and ld then
|
||||||
|
r = r .. " Light: "..l.."/"..ld
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_text(player, bits)
|
||||||
|
local pos = vector.offset(player:get_pos(),0,0.5,0)
|
||||||
|
local bits = bits
|
||||||
|
if bits == 0 then return "" end
|
||||||
|
|
||||||
|
local r = ""
|
||||||
|
for _,key in ipairs(fields_keyset) do
|
||||||
|
local def = mcl_info.registered_debug_fields[key]
|
||||||
|
if def.level == nil or def.level <= bits then
|
||||||
|
r = r ..key..": "..tostring(def.func(player,pos)).."\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
local function info()
|
||||||
|
for _, player in pairs(get_connected_players()) do
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local s = player_setting(player)
|
||||||
|
local pos = player:get_pos()
|
||||||
|
local text = get_text(player, s)
|
||||||
|
local hud = huds[name]
|
||||||
|
if s and not hud then
|
||||||
|
local def = {
|
||||||
|
hud_elem_type = "text",
|
||||||
|
alignment = {x = 1, y = -1},
|
||||||
|
scale = {x = 100, y = 100},
|
||||||
|
position = {x = 0.0073, y = 0.889},
|
||||||
|
text = text,
|
||||||
|
style = 5,
|
||||||
|
["number"] = 0xcccac0,
|
||||||
|
z_index = 0,
|
||||||
|
}
|
||||||
|
local def_bg = table.copy(def)
|
||||||
|
def_bg.offset = {x = 2, y = 1}
|
||||||
|
def_bg["number"] = 0
|
||||||
|
def_bg.z_index = -1
|
||||||
|
huds[name] = {
|
||||||
|
player:hud_add(def),
|
||||||
|
player:hud_add(def_bg),
|
||||||
|
text,
|
||||||
|
}
|
||||||
|
elseif text ~= hud[3] then
|
||||||
|
hud[3] = text
|
||||||
|
player:hud_change(huds[name][1], "text", text)
|
||||||
|
player:hud_change(huds[name][2], "text", text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
after(refresh_interval, info)
|
||||||
|
end
|
||||||
|
info()
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(p)
|
||||||
|
local name = p:get_player_name()
|
||||||
|
huds[name] = nil
|
||||||
|
player_dbg[name] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_chatcommand("debug",{
|
||||||
|
description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 3 = all"),
|
||||||
|
params = S("<bitmask>"),
|
||||||
|
privs = { debug = true },
|
||||||
|
func = function(name, params)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if params == "" then return true, "Debug bitmask is "..player_setting(player) end
|
||||||
|
local dbg = math.floor(tonumber(params) or default_debug)
|
||||||
|
if dbg < 0 or dbg > 4 then
|
||||||
|
minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 4))
|
||||||
|
return false,"Current bitmask: "..player_setting(player)
|
||||||
|
end
|
||||||
|
return true, "Debug bit mask set to "..player_setting(player,dbg)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
mcl_info.register_debug_field("Node feet",{
|
||||||
|
level = 4,
|
||||||
|
func = function(pl,pos)
|
||||||
|
return nodeinfo(pos)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
mcl_info.register_debug_field("Node below",{
|
||||||
|
level = 4,
|
||||||
|
func = function(pl,pos)
|
||||||
|
return nodeinfo(vector.offset(pos,0,-1,0))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
mcl_info.register_debug_field("Biome",{
|
||||||
|
level = 3,
|
||||||
|
func = function(pl,pos)
|
||||||
|
local biome_data = get_biome_data(pos)
|
||||||
|
local biome = biome_data and get_biome_name(biome_data.biome) or "No biome"
|
||||||
|
if biome_data then
|
||||||
|
return format("%s (%s), Humidity: %.1f, Temperature: %.1f",biome, biome_data.biome, biome_data.humidity, biome_data.heat)
|
||||||
|
end
|
||||||
|
return "No biome"
|
||||||
|
end
|
||||||
|
})
|
||||||
|
mcl_info.register_debug_field("Coords",{
|
||||||
|
level = 2,
|
||||||
|
func = function(pl,pos)
|
||||||
|
return format("x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z)
|
||||||
|
end
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
# textdomain: mcl_info
|
||||||
|
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё
|
||||||
|
Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2
|
||||||
|
Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1
|
|
@ -0,0 +1,4 @@
|
||||||
|
# textdomain: mcl_info
|
||||||
|
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=
|
||||||
|
Error! Possible values are integer numbers from @1 to @2=
|
||||||
|
Debug bit mask set to @1=
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = mcl_info
|
||||||
|
description = Prints biome name and player position
|
||||||
|
depends = mcl_init
|
|
@ -59,8 +59,9 @@ minetest.register_globalstep(function(dtime)
|
||||||
local itemstack = mcl_offhand.get_offhand(player)
|
local itemstack = mcl_offhand.get_offhand(player)
|
||||||
local offhand_item = itemstack:get_name()
|
local offhand_item = itemstack:get_name()
|
||||||
local offhand_hud = mcl_offhand[player].hud
|
local offhand_hud = mcl_offhand[player].hud
|
||||||
if offhand_item ~= "" then
|
local item = minetest.registered_items[offhand_item]
|
||||||
local item_texture = minetest.registered_items[offhand_item].inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px
|
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 position = {x = 0.5, y = 1}
|
||||||
local offset = {x = -320, y = -32}
|
local offset = {x = -320, y = -32}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
local GRAVITY = tonumber(minetest.settings:get("movement_gravity"))
|
||||||
local table = table
|
local table = table
|
||||||
|
|
||||||
--register stoppers for movestones/pistons
|
--register stoppers for movestones/pistons
|
||||||
|
@ -328,17 +329,17 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||||
-- Move object at tip of stack, pushpos is position at tip of stack
|
-- Move object at tip of stack, pushpos is position at tip of stack
|
||||||
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
|
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
|
||||||
|
|
||||||
local objects = minetest.get_objects_inside_radius(pushpos, 1)
|
local objects = minetest.get_objects_inside_radius(pushpos, 1.15)
|
||||||
for _, obj in ipairs(objects) do
|
for _, obj in ipairs(objects) do
|
||||||
table.insert(objects_to_move, obj)
|
table.insert(objects_to_move, obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Move objects lying/standing on the stack (before it was pushed - oldstack)
|
-- Move objects lying/standing on the stack (before it was pushed - oldstack)
|
||||||
if tonumber(minetest.settings:get("movement_gravity")) > 0 and dir.y == 0 then
|
if GRAVITY > 0 then
|
||||||
-- If gravity positive and dir horizontal, push players standing on the stack
|
-- If gravity positive and dir horizontal, push players standing on the stack
|
||||||
for _, n in ipairs(nodestack) do
|
for _, n in ipairs(nodestack) do
|
||||||
local p_above = vector.add(n.pos, {x=0, y=1, z=0})
|
local p_above = vector.add(n.pos, {x=0, y=1, z=0})
|
||||||
local objects = minetest.get_objects_inside_radius(p_above, 1)
|
local objects = minetest.get_objects_inside_radius(p_above, 1.15)
|
||||||
for _, obj in ipairs(objects) do
|
for _, obj in ipairs(objects) do
|
||||||
table.insert(objects_to_move, obj)
|
table.insert(objects_to_move, obj)
|
||||||
end
|
end
|
||||||
|
@ -347,7 +348,10 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||||
|
|
||||||
for _, obj in ipairs(objects_to_move) do
|
for _, obj in ipairs(objects_to_move) do
|
||||||
local entity = obj:get_luaentity()
|
local entity = obj:get_luaentity()
|
||||||
if not entity or not mesecon.is_mvps_unmov(entity.name) then
|
local player = obj:is_player()
|
||||||
|
|
||||||
|
|
||||||
|
if not entity or not player and not mesecon.is_mvps_unmov(entity.name) then
|
||||||
local np = vector.add(obj:get_pos(), dir)
|
local np = vector.add(obj:get_pos(), dir)
|
||||||
|
|
||||||
--move only if destination is not solid
|
--move only if destination is not solid
|
||||||
|
@ -355,6 +359,30 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||||
if not ((not minetest.registered_nodes[nn.name])
|
if not ((not minetest.registered_nodes[nn.name])
|
||||||
or minetest.registered_nodes[nn.name].walkable) then
|
or minetest.registered_nodes[nn.name].walkable) then
|
||||||
obj:set_pos(np)
|
obj:set_pos(np)
|
||||||
|
-- Launch Player, TNT & mobs like in Minecraft
|
||||||
|
-- Only doing so if slimeblock is attached.
|
||||||
|
for _, r in ipairs(mesecon.rules.alldirs) do
|
||||||
|
local adjpos = vector.add(np, r)
|
||||||
|
local adjnode = minetest.get_node(adjpos)
|
||||||
|
if minetest.registered_nodes[adjnode.name] and minetest.registered_nodes[adjnode.name].mvps_sticky then
|
||||||
|
local np = vector.add(obj:get_pos(), dir)
|
||||||
|
|
||||||
|
-- Reset acceleration of all objects before launching.
|
||||||
|
-- Fixes eggs, & snowballs thrown by dispensers
|
||||||
|
obj:set_acceleration({x=dir.x, y=-GRAVITY, z=dir.z})
|
||||||
|
|
||||||
|
--Need to set velocities differently for players, items & mobs/tnt, and falling anvils.
|
||||||
|
if player then
|
||||||
|
obj:add_velocity({x = dir.x * 10, y = dir.y * 13, z = dir.z * 10})
|
||||||
|
elseif entity.name == "__builtin:item" then
|
||||||
|
obj:add_velocity({x = dir.x * 9, y = dir.y * 11, z = dir.z * 9})
|
||||||
|
elseif entity.name == "__builtin:falling_node" then
|
||||||
|
obj:add_velocity({x = dir.x * 43, y = dir.y * 72, z = dir.z * 43})
|
||||||
|
else
|
||||||
|
obj:add_velocity({x = dir.x * 6, y = dir.y * 9, z = dir.z * 6})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -117,7 +117,6 @@ for _, def in pairs(bud_def) do
|
||||||
walkable = false,
|
walkable = false,
|
||||||
light_source = def.light_source,
|
light_source = def.light_source,
|
||||||
groups = {
|
groups = {
|
||||||
dig_by_water = 1,
|
|
||||||
destroy_by_lava_flow = 1,
|
destroy_by_lava_flow = 1,
|
||||||
dig_by_piston = 1,
|
dig_by_piston = 1,
|
||||||
pickaxey = 1,
|
pickaxey = 1,
|
||||||
|
@ -162,7 +161,6 @@ minetest.register_node("mcl_amethyst:amethyst_cluster",{
|
||||||
walkable = false,
|
walkable = false,
|
||||||
light_source = 7,
|
light_source = 7,
|
||||||
groups = {
|
groups = {
|
||||||
dig_by_water = 1,
|
|
||||||
destroy_by_lava_flow = 1,
|
destroy_by_lava_flow = 1,
|
||||||
dig_by_piston = 1,
|
dig_by_piston = 1,
|
||||||
pickaxey = 1,
|
pickaxey = 1,
|
||||||
|
|
|
@ -84,6 +84,19 @@ local function distinguish_tool_and_material(input1, input2)
|
||||||
end
|
end
|
||||||
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.
|
-- Update the inventory slots of an anvil node.
|
||||||
-- meta: Metadata of anvil node
|
-- meta: Metadata of anvil node
|
||||||
local function update_anvil_slots(meta)
|
local function update_anvil_slots(meta)
|
||||||
|
@ -213,6 +226,7 @@ local function update_anvil_slots(meta)
|
||||||
|
|
||||||
-- Set the new output slot
|
-- Set the new output slot
|
||||||
if new_output then
|
if new_output then
|
||||||
|
fix_stack_size(new_output)
|
||||||
inv:set_stack("output", 1, new_output)
|
inv:set_stack("output", 1, new_output)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -114,6 +114,10 @@ function mcl_armor.register_set(def)
|
||||||
for k, v in pairs(element_groups) do
|
for k, v in pairs(element_groups) do
|
||||||
groups[k] = v
|
groups[k] = v
|
||||||
end
|
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, {
|
minetest.register_tool(itemstring, {
|
||||||
description = S(def.description .. " " .. (descriptions[name] or element.description)),
|
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,
|
_on_break = on_break_callbacks[name] or def.on_break,
|
||||||
_mcl_armor_element = name,
|
_mcl_armor_element = name,
|
||||||
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
||||||
|
_mcl_upgradable = def._mcl_upgradable,
|
||||||
|
_mcl_upgrade_item = upgrade_item
|
||||||
})
|
})
|
||||||
|
|
||||||
if def.craft_material then
|
if def.craft_material then
|
||||||
|
|
|
@ -49,6 +49,8 @@ mcl_armor.register_set({
|
||||||
},
|
},
|
||||||
repair_material = "mcl_core:iron_ingot",
|
repair_material = "mcl_core:iron_ingot",
|
||||||
cook_material = "mcl_core:iron_nugget",
|
cook_material = "mcl_core:iron_nugget",
|
||||||
|
sound_equip = "mcl_armor_equip_iron",
|
||||||
|
sound_unequip = "mcl_armor_unequip_iron",
|
||||||
})
|
})
|
||||||
|
|
||||||
mcl_armor.register_set({
|
mcl_armor.register_set({
|
||||||
|
@ -64,6 +66,8 @@ mcl_armor.register_set({
|
||||||
},
|
},
|
||||||
craft_material = "mcl_core:iron_ingot",
|
craft_material = "mcl_core:iron_ingot",
|
||||||
cook_material = "mcl_core:iron_nugget",
|
cook_material = "mcl_core:iron_nugget",
|
||||||
|
sound_equip = "mcl_armor_equip_iron",
|
||||||
|
sound_unequip = "mcl_armor_unequip_iron",
|
||||||
})
|
})
|
||||||
|
|
||||||
mcl_armor.register_set({
|
mcl_armor.register_set({
|
||||||
|
@ -79,6 +83,27 @@ mcl_armor.register_set({
|
||||||
},
|
},
|
||||||
toughness = 2,
|
toughness = 2,
|
||||||
craft_material = "mcl_core:diamond",
|
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({
|
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 |
|
@ -0,0 +1,215 @@
|
||||||
|
--[[
|
||||||
|
there are strings in meta, which are being used to see which effect will be given to the player(s)
|
||||||
|
Valid strings:
|
||||||
|
swiftness
|
||||||
|
leaping
|
||||||
|
strenght
|
||||||
|
regeneration
|
||||||
|
]]--
|
||||||
|
--TODO: add beacon beam
|
||||||
|
--TODO: beacons should only work when there are no blocks (few exceptions) above them!
|
||||||
|
--TODO: add translation
|
||||||
|
|
||||||
|
|
||||||
|
local formspec_string=
|
||||||
|
"size[11,14]"..
|
||||||
|
|
||||||
|
"label[4.5,0.5;Beacon:]"..
|
||||||
|
"label[0.5,1;Primary Power:]"..
|
||||||
|
"label[0.5,8.25;Inventory:]"..
|
||||||
|
|
||||||
|
"image[1,1.5;1,1;custom_beacom_symbol_4.png]"..
|
||||||
|
"image[1,3;1,1;custom_beacom_symbol_3.png]"..
|
||||||
|
"image[1,4.5;1,1;custom_beacom_symbol_2.png]"..
|
||||||
|
"image[1,6;1,1;custom_beacom_symbol_1.png]"..
|
||||||
|
|
||||||
|
"image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;]"..
|
||||||
|
"image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;]"..
|
||||||
|
"image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;]"..
|
||||||
|
"image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;]"..
|
||||||
|
|
||||||
|
"item_image[1,7;1,1;mcl_core:diamond]"..
|
||||||
|
"item_image[2.2,7;1,1;mcl_core:emerald]"..
|
||||||
|
"item_image[3.4,7;1,1;mcl_core:iron_ingot]"..
|
||||||
|
"item_image[4.6,7;1,1;mcl_core:gold_ingot]"..
|
||||||
|
|
||||||
|
mcl_formspec.get_itemslot_bg(6,7,1,1)..
|
||||||
|
"list[context;input;6,7;1,1;]"..
|
||||||
|
mcl_formspec.get_itemslot_bg(1,9,9,3)..
|
||||||
|
"list[current_player;main;1,9;9,3;9]"..
|
||||||
|
mcl_formspec.get_itemslot_bg(1,12.5,9,1)..
|
||||||
|
"list[current_player;main;1,12.5;9,1;]"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function beacon_blockcheck(pos)
|
||||||
|
for y_offset = 1,4 do
|
||||||
|
local block_y = pos.y - y_offset
|
||||||
|
for block_x = (pos.x-y_offset),(pos.x+y_offset) do
|
||||||
|
for block_z = (pos.z-y_offset),(pos.z+y_offset) do
|
||||||
|
local valid_block = false --boolean to which stores if block is valid or not
|
||||||
|
for _, beacon_block in pairs(beacon_blocklist) do
|
||||||
|
if beacon_block == minetest.get_node({x=block_x,y=block_y,z=block_z}).name and not valid_block then --is the block in the pyramid a valid beacon block
|
||||||
|
valid_block =true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not valid_block then
|
||||||
|
return y_offset -1 --the last layer is complete, this one is missing or incomplete
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if y_offset == 4 then --all checks are done, beacon is maxed
|
||||||
|
return y_offset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("mcl_beacons:beacon", {
|
||||||
|
--glasslike drawtype?
|
||||||
|
description = "Beacon",
|
||||||
|
tiles = {
|
||||||
|
"beacon_top.png",
|
||||||
|
"beacon_bottom.png",
|
||||||
|
"beacon_side_1.png",
|
||||||
|
"beacon_side_2.png",
|
||||||
|
"beacon_side_3.png",
|
||||||
|
"beacon_side_4.png"
|
||||||
|
},
|
||||||
|
on_construct = function(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
inv:set_size("input", 1)
|
||||||
|
local form = formspec_string
|
||||||
|
meta:set_string("formspec", form)
|
||||||
|
end,
|
||||||
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
|
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then
|
||||||
|
local sender_name = sender:get_player_name()
|
||||||
|
local power_level = beacon_blockcheck(pos)
|
||||||
|
if minetest.is_protected(pos, sender_name) then
|
||||||
|
minetest.record_protection_violation(pos, sender_name)
|
||||||
|
return
|
||||||
|
elseif power_level == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local input = inv:get_stack("input",1)
|
||||||
|
|
||||||
|
if input:is_empty() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local valid_item = false
|
||||||
|
|
||||||
|
for _, item in ipairs(beacon_fuellist) do
|
||||||
|
if input:get_name() == item then
|
||||||
|
valid_item = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if valid_item ~= true then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local successful = false
|
||||||
|
if fields.swiftness then
|
||||||
|
if power_level == 4 then
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",2)
|
||||||
|
else
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",1)
|
||||||
|
end
|
||||||
|
minetest.get_meta(pos):set_string("effect","swiftness")
|
||||||
|
successful = true
|
||||||
|
elseif fields.leaping and power_level >= 2 then
|
||||||
|
if power_level == 4 then
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",2)
|
||||||
|
else
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",1)
|
||||||
|
end
|
||||||
|
minetest.get_meta(pos):set_string("effect","leaping")
|
||||||
|
successful = true
|
||||||
|
elseif fields.strenght and power_level >= 3 then
|
||||||
|
if power_level == 4 then
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",2)
|
||||||
|
else
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",1)
|
||||||
|
end
|
||||||
|
minetest.get_meta(pos):set_string("effect","strenght")
|
||||||
|
successful = true
|
||||||
|
elseif fields.regeneration and power_level == 4 then
|
||||||
|
minetest.get_meta(pos):set_int("effect_level",2)
|
||||||
|
minetest.get_meta(pos):set_string("effect","regeneration")
|
||||||
|
successful = true
|
||||||
|
end
|
||||||
|
if successful then
|
||||||
|
input:take_item()
|
||||||
|
inv:set_stack("input",1,input)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
light_source = 15,
|
||||||
|
sounds = mcl_sounds.node_sound_glass_defaults(),
|
||||||
|
})
|
||||||
|
|
||||||
|
mesecon.register_mvps_stopper("mcl_beacons:beacon")
|
||||||
|
mcl_wip.register_wip_item("mcl_beacons:beacon")
|
||||||
|
|
||||||
|
beacon_blocklist = {"mcl_core:diamondblock","mcl_core:ironblock","mcl_core:goldblock","mcl_core:emeraldblock"}--this is supposed to be a global, don't change that! || TODO: add netherite blocks once implemented!
|
||||||
|
beacon_fuellist ={"mcl_core:diamond","mcl_core:emerald","mcl_core:iron_ingot","mcl_core:gold_ingot"}
|
||||||
|
|
||||||
|
function register_beaconblock (itemstring)--API function for other mods
|
||||||
|
table.insert(beacon_blocklist, itemstring)
|
||||||
|
end
|
||||||
|
|
||||||
|
function register_beaconfuel(itemstring)
|
||||||
|
table.insert(beacon_fuellist, itemstring)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function effect_player(effect,pos,power_level, effect_level)
|
||||||
|
local all_objects = minetest.get_objects_inside_radius(pos, (power_level+1)*10)
|
||||||
|
for _,obj2 in ipairs(all_objects) do
|
||||||
|
if obj2:is_player() then
|
||||||
|
if effect == "swiftness" then
|
||||||
|
mcl_potions.swiftness_func(obj2,effect_level,16)
|
||||||
|
return
|
||||||
|
elseif effect == "leaping" then
|
||||||
|
mcl_potions.leaping_func(obj2, effect_level, 16)
|
||||||
|
return
|
||||||
|
elseif effect == "strenght" then
|
||||||
|
mcl_potions.strength_func(obj2, effect_level, 16)
|
||||||
|
return
|
||||||
|
elseif effect == "regeneration" then
|
||||||
|
mcl_potions.regeneration_func(obj2, effect_level, 16)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function abm_function(pos)
|
||||||
|
local power_level = beacon_blockcheck(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local effect_string = meta:get_string("effect")
|
||||||
|
if meta:get_int("effect_level") == 2 and power_level < 4 then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
effect_player(effect_string,pos,power_level,meta:get_int("effect_level"))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_abm{
|
||||||
|
label = "beacon check & apply effect(s)",
|
||||||
|
nodenames = {"mcl_beacons:beacon"},
|
||||||
|
interval = 5,
|
||||||
|
chance = 1,
|
||||||
|
action = abm_function,
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
author=chmodsayshello
|
||||||
|
depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds
|
After Width: | Height: | Size: 338 B |
After Width: | Height: | Size: 339 B |
After Width: | Height: | Size: 337 B |
After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 338 B |
After Width: | Height: | Size: 340 B |