Compare commits

..

34 Commits

Author SHA1 Message Date
AFCMS 225650904c Merge branch 'master' into api-cauldrons 2021-03-31 20:33:18 +02:00
AFCMS 1b144d507d Merge branch 'master' into api-cauldrons 2021-03-31 16:15:53 +02:00
AFCMS 738519f0a4 Merge branch 'master' into api-cauldrons 2021-03-30 22:28:33 +02:00
AFCMS d1ca012ea0 small API fix 2021-03-27 12:27:46 +01:00
AFCMS a18a2127c5 add helper function to give item in creative 2021-03-27 12:20:14 +01:00
AFCMS 7156afcd03 add helper functio nto give item 2021-03-27 12:16:08 +01:00
AFCMS e3b3e2343b fix crash 2021-03-27 12:08:00 +01:00
AFCMS 6f23351126 move every function in the right place 2021-03-27 12:06:52 +01:00
AFCMS a99619774d move more functions 2021-03-27 12:03:14 +01:00
AFCMS 989384f362 move is_cauldron to the right place 2021-03-27 11:57:07 +01:00
AFCMS 69da355f96 fix API design 2021-03-27 11:55:22 +01:00
AFCMS 297d4e707c WIP separate functions into different files 2021-03-27 11:52:54 +01:00
AFCMS b4033ddfc9 Merge branch 'master' into api-cauldrons 2021-03-27 11:35:24 +01:00
AFCMS c35c8a1713 Merge branch 'master' into api-cauldrons 2021-03-19 15:12:54 +01:00
AFCMS 64b49ba719 try to fix give function 2021-03-19 14:58:25 +01:00
AFCMS d00490c86f fix stupid crash 2021-03-19 14:27:57 +01:00
AFCMS 8c91d23eb8 fix give function 2021-03-19 14:26:43 +01:00
AFCMS 294cb3eb7d cleanup 2021-03-19 14:17:59 +01:00
AFCMS cf4d57e584 fix crash 2021-03-19 14:13:34 +01:00
AFCMS 890b95bb49 Merge branch 'master' into api-cauldrons 2021-03-19 13:39:17 +01:00
AFCMS 8611d27f1d init function 2021-03-19 10:23:22 +01:00
AFCMS 59892abf6d fix 2021-03-19 10:19:08 +01:00
AFCMS e69365f44d init give function 2021-03-19 10:18:15 +01:00
AFCMS aa0c7bd2cf Merge branch 'master' into api-cauldrons 2021-03-19 10:16:27 +01:00
AFCMS 2b73c16c69 fix doc 2 2021-03-18 20:58:06 +01:00
AFCMS 36f479b2ec cleanup 2021-03-18 20:52:24 +01:00
AFCMS 717a18ef16 fix doc 2021-03-18 20:50:37 +01:00
AFCMS 9b0c87dabc fixes 2021-03-18 19:43:25 +01:00
AFCMS 3c83898095 quick fix 2021-03-18 19:30:53 +01:00
AFCMS 6ebae965f6 fixes 2021-03-18 19:27:43 +01:00
AFCMS 5e5b3ebf75 WIP API for mcl_cauldrons 2021-03-18 19:18:35 +01:00
AFCMS e68736a040 WIP 2021-03-18 18:02:08 +01:00
AFCMS 72149a2c56 part 2 2021-03-18 09:43:31 +01:00
AFCMS 182e825303 init mcl_cauldrons API (WIP) 2021-03-17 21:47:27 +01:00
126 changed files with 999 additions and 4613 deletions

View File

@ -1,8 +1,5 @@
# This is a game specific minetest.conf file, do not edit
# If any of these settings are set in your minetest.conf file in ~/.minetest (Linux) or in the root directory of the game (Run in place/Windows)
# They will override these settings
# Basic game rules
time_speed = 72
@ -36,7 +33,7 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
keepInventory = false
# Performance settings
dedicated_server_step = 0.05 #tick rate
# dedicated_server_step = 0.001
# abm_interval = 0.25
# max_objects_per_block = 4096
# max_packets_per_iteration = 10096

View File

@ -1,23 +0,0 @@
# controls
## controls.players
Table containing player controls at runtime.
WARNING: Never use this table in writing
## controls.register_on_press(func)
Register a function that will be executed with (player, keyname) every time a player press a key.
## controls.registered_on_press
Table containing functions registered with controls.register_on_press().
## controls.register_on_release(func)
Register a function that will be executed with (player, keyname, clock_from_last_press) every time a player release a key.
## controls.registered_on_release
Table containing functions registered with controls.register_on_release().
## controls.register_on_hold(func)
Register a function that will be executed with (player, keyname, clock_from_start_hold) every time a player hold a key.
## controls.registered_on_hold
Table containing functions registered with controls.register_on_hold().

View File

@ -1,45 +0,0 @@
# flowlib
Simple flow functions.
## flowlib.is_touching(realpos, nodepos, radius)
Return true if a sphere of <radius> at <realpos> collide with node at <nodepos>.
* realpos: position
* nodepos: position
* radius: number
## flowlib.is_water(pos)
Return true if node at <pos> is water, false overwise.
* pos: position
## flowlib.node_is_water(node)
Return true if <node> is water, false overwise.
* node: node
## flowlib.is_lava(pos)
Return true if node at <pos> is lava, false overwise.
* pos: position
## flowlib.node_is_lava(node)
Return true if <node> is lava, false overwise.
* node: node
## flowlib.is_liquid(pos)
Return true if node at <pos> is liquid, false overwise.
* pos: position
## flowlib.node_is_liquid(node)
Return true if <node> is liquid, false overwise.
* node: node
## flowlib.quick_flow(pos, node)
Return direction where the water is flowing (to be use to push mobs, items...).
* pos: position
* node: node
## flowlib.move_centre(pos, realpos, node, radius)
Return the pos of the nearest not water block near from <pos> in a sphere of <radius> at <realpos>.
WARNING: This function is never used in mcl2, use at your own risk. The informations described here may be wrong.
* pos: position
* realpos: position, position of the entity
* node: node
* radius: number

View File

@ -1,27 +0,0 @@
# mcl_autogroup
This mod emulate digging times from mc.
## mcl_autogroup.can_harvest(nodename, toolname)
Return true if <nodename> can be dig with <toolname>.
* nodename: string, valid nodename
* toolname: (optional) string, valid toolname
## mcl_autogroup.get_groupcaps(toolname, efficiency)
This function is used to calculate diggroups for tools.
WARNING: This function can only be called after mod initialization.
* toolname: string, name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
* efficiency: (optional) integer, the efficiency level the tool is enchanted with (default 0)
## mcl_autogroup.get_wear(toolname, diggroup)
Return the max wear of <toolname> with <diggroup>
WARNING: This function can only be called after mod initialization.
* toolname: string, name of the tool used
* diggroup: string, the name of the diggroup the tool is used on
## mcl_autogroup.register_diggroup(group, def)
* group: string, name of the group to register as a digging group
* def: (optional) table, table with information about the diggroup (defaults to {} if unspecified)
* level: (optional) string, if specified it is an array containing the names of the different digging levels the digging group supports
## mcl_autogroup.registered_diggroups
List of registered diggroups, indexed by name.

View File

@ -1,8 +0,0 @@
# mcl_colors
Mod providing global table containing legacity minecraft colors to be used in mods.
## mcl_colors.*
Colors by upper name, in hex value.
## mcl_colors.background.*
Background colors by upper name, in hex value.

View File

@ -1,15 +0,0 @@
# mcl_explosions
This mod provide helper functions to create explosions.
## mcl_explosions.explode(pos, strength, info, puncher)
* pos: position, initial position of the explosion
* strenght: number, radius of the explosion
* info: table, explosion informations:
* drop_chance: number, if specified becomes the drop chance of all nodes in the explosion (default: 1.0 / strength)
* max_blast_resistance: int, if specified the explosion will treat all non-indestructible nodes as having a blast resistance of no more than this value
* sound: bool, if true, the explosion will play a sound (default: true)
* particles: bool, if true, the explosion will create particles (default: true)
* fire: bool, if true, 1/3 nodes become fire (default: false)
* griefing: bool, if true, the explosion will destroy nodes (default: true)
* grief_protected: bool, if true, the explosion will also destroy nodes which have been protected (default: false)
* puncher: (optional) entity, will be used as source for damage done by the explosion

View File

@ -21,9 +21,6 @@ mcl_vars.gui_bg_img = "background9[1,1;1,1;mcl_base_textures_background9.png;tru
-- Legacy
mcl_vars.inventory_header = ""
-- Tool wield size
mcl_vars.tool_wield_scale = { x = 1.8, y = 1.8, z = 1 }
-- Mapgen variables
local mg_name = minetest.get_mapgen_setting("mg_name")
local minecraft_height_limit = 256

View File

@ -410,7 +410,7 @@ function mcl_util.get_color(colorstr)
local mc_color = mcl_colors[colorstr:upper()]
if mc_color then
colorstr = mc_color
elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#" then
elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then
return
end
local hex = tonumber(colorstr:sub(2, 7), 16)

View File

@ -1,80 +0,0 @@
# mcl_worlds
This mod provides utility functions about positions and dimensions.
## mcl_worlds.is_in_void(pos)
This function returns:
* true, true: if pos is in deep void (deadly)
* true, false: if the pos is in void (non deadly)
* false, false: owerwise
Params:
* pos: position
## mcl_worlds.y_to_layer(y)
This function is used to calculate the minetest y layer and dimension of the given <y> minecraft layer.
Mainly used for ore generation.
Takes an Y coordinate as input and returns:
* The corresponding Minecraft layer (can be nil if void)
* The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if <y> is in the void
If the Y coordinate is not located in any dimension, it will return: nil, "void"
Params:
* y: int
## mcl_worlds.pos_to_dimension(pos)
This function return the Minecraft dimension of <pos> ("overworld", "nether" or "end") or "void" if <y> is in the void.
* pos: position
## mcl_worlds.layer_to_y(layer, mc_dimension)
Takes a Minecraft layer and a “dimension” name and returns the corresponding Y coordinate for MineClone 2.
mc_dimension can be "overworld", "nether", "end" (default: "overworld").
* layer: int
* mc_dimension: string
## mcl_worlds.has_weather(pos)
Returns true if <pos> can have weather, false owerwise.
Weather can be only in the overworld.
* pos: position
## mcl_worlds.has_dust(pos)
Returns true if <pos> can have nether dust, false owerwise.
Nether dust can be only in the nether.
* pos: position
## mcl_worlds.compass_works(pos)
Returns true if compasses are working at <pos>, false owerwise.
In mc, you cant use compass in the nether and the end.
* pos: position
## mcl_worlds.compass_works(pos)
Returns true if clock are working at <pos>, false owerwise.
In mc, you cant use clock in the nether and the end.
* pos: position
## mcl_worlds.register_on_dimension_change(function(player, dimension))
Register a callback function func(player, dimension).
It will be called whenever a player changes between dimensions.
The void counts as dimension.
* player: player, the player who changed the dimension
* dimension: position, The new dimension of the player ("overworld", "nether", "end", "void").
## mcl_worlds.registered_on_dimension_change
Table containing all function registered with mcl_worlds.register_on_dimension_change()
## mcl_worlds.dimension_change(player, dimension)
Notify this mod of a dimmension change of <player> to <dimension>
* player: player, player who changed the dimension
* dimension: string, new dimension ("overworld", "nether", "end", "void")

View File

@ -1,36 +1,14 @@
--these are lua locals, used for higher performance
local minetest,math,vector,ipairs = minetest,math,vector,ipairs
--this is used for the player pool in the sound buffer
local pool = {}
local tick = false
minetest.register_on_joinplayer(function(player)
local name
name = player:get_player_name()
pool[name] = 0
end)
minetest.register_on_leaveplayer(function(player)
local name
name = player:get_player_name()
pool[name] = nil
end)
local has_awards = minetest.get_modpath("awards")
local mcl_item_entity = {}
mcl_item_entity = {}
--basic settings
local item_drop_settings = {} --settings table
item_drop_settings.dug_buffer = 0.65 -- the warm up period before a dug item can be collected
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect!
item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect!
item_drop_settings.radius_collect = 0.2 --radius of collection
item_drop_settings.player_collect_height = 0.8 --added to their pos y value
item_drop_settings.player_collect_height = 1.0 --added to their pos y value
item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers
item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0
item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack
@ -96,71 +74,103 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
end
end
minetest.register_globalstep(function(dtime)
tick = not tick
for _,player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
local name = player:get_player_name()
local pos = player:get_pos()
if tick == true and pool[name] > 0 then
minetest.sound_play("item_drop_pickup", {
pos = pos,
gain = 0.7,
max_hear_distance = 16,
pitch = math.random(70,110)/100
})
if pool[name] > 6 then
pool[name] = 6
else
pool[name] = pool[name] - 1
end
end
local inv = player:get_inventory()
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
--magnet and collection
for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
local collected = false
if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
-- Collection
if not object:get_luaentity()._removed then
if vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
-- Ignore if itemstring is not set yet
if object:get_luaentity().itemstring ~= "" then
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
minetest.sound_play("item_drop_pickup", {
pos = pos,
max_hear_distance = 16,
gain = 1.0,
}, true)
check_pickup_achievements(object, player)
-- Destroy entity
-- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
object:get_luaentity().target = checkpos
object:get_luaentity()._removed = true
object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=0,z=0})
object:move_to(checkpos)
pool[name] = pool[name] + 1
minetest.after(0.25, function()
--safety check
if object and object:get_luaentity() then
object:remove()
end
end)
object:remove()
collected = true
end
-- Magnet
else
object:get_luaentity()._magnet_active = true
object:get_luaentity()._collector_timer = 0
-- Move object to player
disable_physics(object, object:get_luaentity())
local opos = object:get_pos()
local vec = vector.subtract(checkpos, opos)
vec = vector.add(opos, vector.divide(vec, 2))
object:move_to(vec)
--fix eternally falling items
minetest.after(0, function(object)
local lua = object:get_luaentity()
if lua then
object:set_acceleration({x=0, y=0, z=0})
end
end, object)
--this is a safety to prevent items flying away on laggy servers
if item_drop_settings.collection_safety == true then
if object:get_luaentity().init ~= true then
object:get_luaentity().init = true
minetest.after(1, function(args)
local playername = args[1]
local player = minetest.get_player_by_name(playername)
local object = args[2]
local lua = object:get_luaentity()
if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then
return
end
if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
if not object:get_luaentity()._removed then
minetest.sound_play("item_drop_pickup", {
pos = pos,
max_hear_distance = 16,
gain = 1.0,
}, true)
end
check_pickup_achievements(object, player)
object:get_luaentity()._removed = true
object:remove()
else
enable_physics(object, object:get_luaentity())
end
end, {player:get_player_name(), object})
end
end
end
end
if not collected then
if object:get_luaentity()._magnet_timer > 1 then
object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time
object:get_luaentity()._magnet_active = false
elseif object:get_luaentity()._magnet_timer < 0 then
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
end
end
@ -220,13 +230,12 @@ local function get_fortune_drops(fortune_drops, fortune_level)
return drop or {}
end
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
function minetest.handle_node_drops(pos, drops, digger)
-- NOTE: This function override allows digger to be nil.
-- This means there is no digger. This is a special case which allows this function to be called
-- by hand. Creative Mode is intentionally ignored in this case.
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then
return
end
@ -326,10 +335,6 @@ function minetest.handle_node_drops(pos, drops, digger)
z = -z
end
obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z})
obj:get_luaentity().age = item_drop_settings.dug_buffer
obj:get_luaentity()._insta_collect = false
end
end
end
@ -396,9 +401,6 @@ minetest.register_entity(":__builtin:item", {
-- Number of seconds this item entity has existed so far
age = 0,
-- How old it has become in the collection animation
collection_age = 0,
set_item = function(self, itemstring)
self.itemstring = itemstring
if self.itemstring == "" then
@ -564,11 +566,6 @@ minetest.register_entity(":__builtin:item", {
on_step = function(self, dtime)
if self._removed then
self.object:set_properties({
physical = false
})
self.object:set_velocity({x=0,y=0,z=0})
self.object:set_acceleration({x=0,y=0,z=0})
return
end
self.age = self.age + dtime

View File

@ -1 +0,0 @@
Item_Drop_Pickup - https://freesound.org/people/benniknop/sounds/317848/ (License: CC0)

View File

@ -61,6 +61,8 @@ end
-- Load settings
local damage_enabled = minetest.settings:get_bool("enable_damage")
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
@ -82,6 +84,11 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then
end)
end
-- calculate aoc range for mob count
local aosrb = tonumber(minetest.settings:get("active_object_send_range_blocks"))
local abr = tonumber(minetest.settings:get("active_block_range"))
local aoc_range = max(aosrb, abr) * 16
-- pathfinding settings
local enable_pathfinding = true
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
@ -728,9 +735,7 @@ local item_drop = function(self, cooked, looting_level)
end
-- add item if it exists
for x = 1, num do
obj = minetest.add_item(pos, ItemStack(item .. " " .. 1))
end
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
if obj and obj:get_luaentity() then
@ -859,12 +864,10 @@ local check_for_death = function(self, cause, cmi_cause)
remove_texture_mod(self, "^[colorize:#FF000040")
remove_texture_mod(self, "^[brighten")
self.passive = true
self.object:set_properties({
pointable = false,
collide_with_objects = false,
})
set_velocity(self, 0)
local acc = self.object:get_acceleration()
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
@ -2814,10 +2817,6 @@ local do_states = function(self, dtime)
local arrow, ent
local v = 1
if not self.shoot_arrow then
self.firing = true
minetest.after(1, function()
self.firing = false
end)
arrow = minetest.add_entity(p, self.arrow)
ent = arrow:get_luaentity()
if ent.velocity then
@ -3521,6 +3520,14 @@ local mob_step = function(self, dtime)
-- end rotation
-- knockback timer
if self.pause_timer > 0 then
self.pause_timer = self.pause_timer - dtime
return
end
-- run custom function (defined in mob lua file)
if self.do_custom then
@ -3530,14 +3537,6 @@ local mob_step = function(self, dtime)
end
end
-- knockback timer
if self.pause_timer > 0 then
self.pause_timer = self.pause_timer - dtime
return
end
-- attack timer
self.timer = self.timer + dtime
@ -3556,7 +3555,7 @@ local mob_step = function(self, dtime)
end
-- mob plays random sound at times
if random(1, 70) == 1 then
if random(1, 100) == 1 then
mob_sound(self, "random", true)
end
@ -3736,8 +3735,6 @@ function mobs:register_mob(name, def)
local can_despawn
if def.can_despawn ~= nil then
can_despawn = def.can_despawn
elseif def.spawn_class == "passive" then
can_despawn = false
else
can_despawn = true
end
@ -3901,12 +3898,6 @@ minetest.register_entity(name, {
on_detach_child = mob_detach_child,
on_activate = function(self, staticdata, dtime)
--this is a temporary hack so mobs stop
--glitching and acting really weird with the
--default built in engine collision detection
self.object:set_properties({
collide_with_objects = false,
})
return mob_activate(self, staticdata, def, dtime)
end,
@ -3925,6 +3916,289 @@ end
end -- END mobs:register_mob function
-- count how many mobs of one type are inside an area
local count_mobs = function(pos, mobtype)
local num = 0
local objs = minetest.get_objects_inside_radius(pos, aoc_range)
for n = 1, #objs do
local obj = objs[n]:get_luaentity()
if obj and obj.name and obj._cmi_is_mob then
-- count passive mobs only
if mobtype == "!passive" then
if obj.spawn_class == "passive" then
num = num + 1
end
-- count hostile mobs only
elseif mobtype == "!hostile" then
if obj.spawn_class == "hostile" then
num = num + 1
end
-- count ambient mobs only
elseif mobtype == "!ambient" then
if obj.spawn_class == "ambient" then
num = num + 1
end
-- count water mobs only
elseif mobtype == "!water" then
if obj.spawn_class == "water" then
num = num + 1
end
-- count mob type
elseif mobtype and obj.name == mobtype then
num = num + 1
-- count total mobs
elseif not mobtype then
num = num + 1
end
end
end
return num
end
-- global functions
function mobs:spawn_abm_check(pos, node, name)
-- global function to add additional spawn checks
-- return true to stop spawning mob
end
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
-- Do mobs spawn at all?
if not mobs_spawn then
return
end
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)
if numbers then
numbers = numbers:split(",")
chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action",
string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
local spawn_action
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos)
-- is mob actually registered?
if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then
minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!")
return
end
-- additional custom checks for spawning mob
if mobs:spawn_abm_check(pos, node, name) == true then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!")
return
end
-- count nearby mobs in same spawn class
local entdef = minetest.registered_entities[name]
local spawn_class = entdef and entdef.spawn_class
if not spawn_class then
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
end
local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class]
-- do not spawn if too many of same mob in area
if active_object_count_wider >= max_per_block -- large-range mob cap
or (not in_class_cap) -- spawn class mob cap
or count_mobs(pos, name) >= aoc then -- per-mob mob cap
-- too many entities
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!")
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
-- mob needs night
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!")
return
end
else
-- night time but mob wants day
if day_toggle == true then
-- mob needs day
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!")
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
-- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 24)
for n = 1, #objs do
if objs[n]:is_player() then
-- player too close
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!")
return
end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!")
return
end
-- are we spawning within height limits?
if pos.y > max_height
or pos.y < min_height then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!")
return
end
-- are light levels ok?
local light = minetest.get_node_light(pos)
if not light
or light > max_light
or light < min_light then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!")
return
end
-- do we have enough space to spawn mob?
local ent = minetest.registered_entities[name]
local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x
if width_x % 2 == 0 then
max_x = math.floor(width_x/2)
min_x = -(max_x-1)
else
max_x = math.floor(width_x/2)
min_x = -max_x
end
local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z/2)
min_z = -(max_z-1)
else
max_z = math.floor(width_z/2)
min_z = -max_z
end
local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
-- inside block
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
end
return
end
end
end
end
-- tweak X/Y/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
if on_spawn then
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end
end
local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider, name)
end
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = floor(max(1, chance * mobs_spawn_chance)),
catch_up = false,
action = spawn_abm_action,
})
end
-- compatibility with older mob registration
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height, day_toggle)
end
-- MarkBu's spawn function
function mobs:spawn(def)
local name = def.name
local nodes = def.nodes or {"group:soil", "group:stone"}
local neighbors = def.neighbors or {"air"}
local min_light = def.min_light or 0
local max_light = def.max_light or 15
local interval = def.interval or 30
local chance = def.chance or 5000
local active_object_count = def.active_object_count or 1
local min_height = def.min_height or -31000
local max_height = def.max_height or 31000
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
end
-- register arrow for shoot attack
function mobs:register_arrow(name, def)
@ -3947,11 +4221,6 @@ function mobs:register_arrow(name, def)
switch = 0,
owner_id = def.owner_id,
rotate = def.rotate,
on_punch = function(self)
local vel = self.object:get_velocity()
self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1})
end,
collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0},
automatic_face_movement_dir = def.rotate
and (def.rotate - (pi / 180)) or false,
@ -4014,7 +4283,7 @@ function mobs:register_arrow(name, def)
if self.hit_player or self.hit_mob or self.hit_object then
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do
if self.hit_player
and player:is_player() then
@ -4069,7 +4338,7 @@ end
-- make explosion with protection and tnt mod check
function mobs:boom(self, pos, strength, fire)
self.object:remove()
if mod_explosions then
if mobs_griefing and not minetest.is_protected(pos, "") then
mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object)
@ -4350,7 +4619,6 @@ function mobs:alias_mob(old_name, new_name)
end
--[[
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
@ -4367,4 +4635,3 @@ minetest.register_globalstep(function(dtime)
end
timer = 0
end)
]]--

View File

@ -4,11 +4,8 @@ local path = minetest.get_modpath(minetest.get_current_modname())
-- Mob API
dofile(path .. "/api.lua")
-- Spawning Algorithm
dofile(path .. "/spawning.lua")
-- Rideable Mobs
dofile(path .. "/mount.lua")
-- Mob Items
dofile(path .. "/crafts.lua")
dofile(path .. "/crafts.lua")

View File

@ -168,20 +168,16 @@ function mobs.detach(player, offset)
mcl_player.player_set_animation(player, "stand" , 30)
--local pos = player:get_pos()
local pos = player:get_pos()
--pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
player:add_velocity(vector.new(math.random(-6,6),math.random(5,8),math.random(-6,6))) --throw the rider off
--[[
minetest.after(0.1, function(name, pos)
local player = minetest.get_player_by_name(name)
if player then
player:set_pos(pos)
end
end, player:get_player_name(), pos)
]]--
end

View File

@ -1,648 +0,0 @@
--lua locals
local get_node = minetest.get_node
local get_item_group = minetest.get_item_group
local get_node_light = minetest.get_node_light
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
local new_vector = vector.new
local math_random = math.random
local get_biome_name = minetest.get_biome_name
local max = math.max
local get_objects_inside_radius = minetest.get_objects_inside_radius
local vector_distance = vector.distance
-- range for mob count
local aoc_range = 32
--[[
THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
underground:
"FlowerForest_underground",
"JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
ocean:
"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",
water or beach?
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
beach:
"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",
dimension biome:
"Nether",
"End",
Overworld regular:
"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",
]]--
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
-- count how many mobs of one type are inside an area
local count_mobs = function(pos,mobtype)
print(mobtype)
local num = 0
local objs = get_objects_inside_radius(pos, aoc_range)
for n = 1, #objs do
local obj = objs[n]:get_luaentity()
if obj and obj.name and obj._cmi_is_mob then
-- count hostile mobs only
if mobtype == "hostile" then
if obj.spawn_class == "hostile" then
num = num + 1
end
-- count passive mobs only
else
num = num + 1
end
end
end
return num
end
-- global functions
function mobs:spawn_abm_check(pos, node, name)
-- global function to add additional spawn checks
-- return true to stop spawning mob
end
--[[
Custom elements changed:
name:
the mobs name
dimension:
"overworld"
"nether"
"end"
types of spawning:
"water"
"ground"
"lava"
biomes: tells the spawner to allow certain mobs to spawn in certain biomes
{"this", "that", "grasslands", "whatever"}
what is aoc??? objects in area
WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
]]--
--this is where all of the spawning information is kept
local spawn_dictionary = {}
function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
--print(dump(biomes))
-- Do mobs spawn at all?
if not mobs_spawn then
return
end
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)
if numbers then
numbers = numbers:split(",")
chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action",
string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
--[[
local spawn_action
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos)
-- is mob actually registered?
if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then
minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!")
return
end
-- additional custom checks for spawning mob
if mobs:spawn_abm_check(pos, node, name) == true then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!")
return
end
-- count nearby mobs in same spawn class
local entdef = minetest.registered_entities[name]
local spawn_class = entdef and entdef.spawn_class
if not spawn_class then
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
end
local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class]
-- do not spawn if too many of same mob in area
if active_object_count_wider >= max_per_block -- large-range mob cap
or (not in_class_cap) -- spawn class mob cap
or count_mobs(pos, name) >= aoc then -- per-mob mob cap
-- too many entities
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!")
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
-- mob needs night
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!")
return
end
else
-- night time but mob wants day
if day_toggle == true then
-- mob needs day
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!")
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
-- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 24)
for n = 1, #objs do
if objs[n]:is_player() then
-- player too close
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!")
return
end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!")
return
end
-- are we spawning within height limits?
if pos.y > max_height
or pos.y < min_height then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!")
return
end
-- are light levels ok?
local light = minetest.get_node_light(pos)
if not light
or light > max_light
or light < min_light then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!")
return
end
-- do we have enough space to spawn mob?
local ent = minetest.registered_entities[name]
local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x
if width_x % 2 == 0 then
max_x = math.floor(width_x/2)
min_x = -(max_x-1)
else
max_x = math.floor(width_x/2)
min_x = -max_x
end
local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z/2)
min_z = -(max_z-1)
else
max_z = math.floor(width_z/2)
min_z = -max_z
end
local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
-- inside block
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
end
return
end
end
end
end
-- tweak X/Y/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
if on_spawn then
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end
end
local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider, name)
end
]]--
local entdef = minetest.registered_entities[name]
local spawn_class
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
--load information into the spawn dictionary
local key = #spawn_dictionary + 1
spawn_dictionary[key] = {}
spawn_dictionary[key]["name"] = name
spawn_dictionary[key]["dimension"] = dimension
spawn_dictionary[key]["type_of_spawning"] = type_of_spawning
spawn_dictionary[key]["biomes"] = biomes
spawn_dictionary[key]["min_light"] = min_light
spawn_dictionary[key]["max_light"] = max_light
spawn_dictionary[key]["interval"] = interval
spawn_dictionary[key]["chance"] = chance
spawn_dictionary[key]["aoc"] = aoc
spawn_dictionary[key]["min_height"] = min_height
spawn_dictionary[key]["max_height"] = max_height
spawn_dictionary[key]["day_toggle"] = day_toggle
--spawn_dictionary[key]["on_spawn"] = spawn_abm_action
spawn_dictionary[key]["spawn_class"] = spawn_class
--[[
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = floor(max(1, chance * mobs_spawn_chance)),
catch_up = false,
action = spawn_abm_action,
})
]]--
end
-- compatibility with older mob registration
-- we're going to forget about this for now -j4i
--[[
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height, day_toggle)
end
]]--
--Don't disable this yet-j4i
-- MarkBu's spawn function
function mobs:spawn(def)
--does nothing for now
--[[
local name = def.name
local nodes = def.nodes or {"group:soil", "group:stone"}
local neighbors = def.neighbors or {"air"}
local min_light = def.min_light or 0
local max_light = def.max_light or 15
local interval = def.interval or 30
local chance = def.chance or 5000
local active_object_count = def.active_object_count or 1
local min_height = def.min_height or -31000
local max_height = def.max_height or 31000
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
]]--
end
local axis
--inner and outer part of square donut radius
local inner = 1
local outer = 65
local int = {-1,1}
local position_calculation = function(pos)
pos = vector.floor(pos)
--this is used to determine the axis buffer from the player
axis = math.random(0,1)
--cast towards the direction
if axis == 0 then --x
pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)]
pos.z = pos.z + math.random(-outer,outer)
else --z
pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)]
pos.x = pos.x + math.random(-outer,outer)
end
return(pos)
end
--[[
local decypher_limits_dictionary = {
["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max},
["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max},
["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max}
}
]]--
local function decypher_limits(posy)
--local min_max_table = decypher_limits_dictionary[dimension]
--return min_max_table[1],min_max_table[2]
posy = math.floor(posy)
return posy - 32, posy + 32
end
--a simple helper function for mob_spawn
local function biome_check(biome_list, biome_goal)
for _,data in ipairs(biome_list) do
if data == biome_goal then
return true
end
end
return false
end
--todo mob limiting
--MAIN LOOP
if mobs_spawn then
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer >= 8 then
timer = 0
for _,player in pairs(minetest.get_connected_players()) do
for i = 1,math_random(3,8) do
repeat -- after this line each "break" means "continue"
local player_pos = player:get_pos()
local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
if dimension == "void" or dimension == "default" then
break -- ignore void and unloaded area
end
local min,max = decypher_limits(player_pos.y)
local goal_pos = position_calculation(player_pos)
local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"})
--couldn't find node
if #spawning_position_list <= 0 then
break
end
local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)]
--Prevent strange behavior/too close to player
if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then
break
end
local gotten_node = get_node(spawning_position).name
if not gotten_node or gotten_node == "air" then --skip air nodes
break
end
local gotten_biome = minetest.get_biome_data(spawning_position)
if not gotten_biome then
break --skip if in unloaded area
end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
--grab random mob
local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)]
if not mob_def then
break --skip if something ridiculous happens (nil mob def)
end
--skip if not correct dimension
if mob_def.dimension ~= dimension then
break
end
--skip if not in correct biome
if not biome_check(mob_def.biomes, gotten_biome) then
break
end
--add this so mobs don't spawn inside nodes
spawning_position.y = spawning_position.y + 1
if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then
break
end
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(spawning_position)
--don't spawn if not in light limits
if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then
break
end
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
if mob_def.type_of_spawning == "ground" and is_water then
break
end
if mob_def.type_of_spawning == "ground" and is_lava then
break
end
--finally do the heavy check (for now) of mobs in area
if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then
break
end
--adjust the position for water and lava mobs
if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then
spawning_position.y = spawning_position.y - 1
end
--everything is correct, spawn mob
minetest.add_entity(spawning_position, mob_def.name)
until true --this is a safety catch
end
end
end
end)
end

View File

@ -290,13 +290,13 @@ mobs_mc.spawn = {
mobs_mc.spawn_height = {
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
-- Overworld boundaries (inclusive) --I adjusted this to be more reasonable
overworld_min = -64,-- -2999,
-- Overworld boundaries (inclusive)
overworld_min = -2999,
overworld_max = 31000,
-- Nether boundaries (inclusive)
nether_min = -29067,-- -3369,
nether_max = -28939,-- -3000,
nether_min = -3369,
nether_max = -3000,
-- End boundaries (inclusive)
end_min = -6200,

View File

@ -1,5 +1,5 @@
--###################
--################### AGENT - seemingly unused
--################### AGENT
--###################
local S = minetest.get_translator("mobs_mc")

View File

@ -64,81 +64,7 @@ else
end
-- Spawn on solid blocks at or below Sea level and the selected light level
mobs:spawn_specific(
"mobs_mc:bat",
"overworld",
"ground",
{
"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",
"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",
},
0,
maxlight,
20,
5000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.water-1)
mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1)
-- spawn eggs

View File

@ -1,6 +1,6 @@
-- daufinsyd
-- My work is under the LGPL terms
-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez
-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models
-- blaze.lua partial copy of mobs_mc/ghast.lua
local S = minetest.get_translator("mobs_mc")
@ -75,71 +75,9 @@ mobs:register_mob("mobs_mc:blaze", {
fear_height = 0,
glow = 14,
fire_resistant = true,
do_custom = function(self)
if self.state == "attack" and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then
mcl_burning.set_on_fire(self.attack, 5)
end
local pos = self.object:get_pos()
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,
vertical = false,
texture = "mcl_particles_smoke_anim.png^[colorize:#2c2c2c:255",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
})
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,
vertical = false,
texture = "mcl_particles_smoke_anim.png^[colorize:#424242:255",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
})
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,
vertical = false,
texture = "mcl_particles_smoke_anim.png^[colorize:#0f0f0f:255",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
})
end,
})
mobs:spawn_specific(
"mobs_mc:blaze",
"nether",
"ground",
{"Nether"},
0,
minetest.LIGHT_MAX+1,
30,
5000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- Blaze fireball
mobs:register_arrow("mobs_mc:blaze_fireball", {

View File

@ -100,34 +100,7 @@ mobs:register_mob("mobs_mc:chicken", {
})
--spawn
mobs:spawn_specific(
"mobs_mc:chicken",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30, 17000,
3,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)

View File

@ -145,53 +145,8 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
-- Spawning
mobs:spawn_specific(
"mobs_mc:cow",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
17000,
10,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:mooshroom",
"overworld",
"ground",
{
"MushroomIslandShore",
"MushroomIsland"
},
9,
minetest.LIGHT_MAX+1,
30,
17000,
5,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn egg
mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)

View File

@ -39,8 +39,6 @@ mobs:register_mob("mobs_mc:creeper", {
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
attack_type = "explode",
--hssssssssssss
explosion_strength = 3,
explosion_radius = 3.5,
explosion_damage_radius = 3.5,
@ -78,6 +76,7 @@ mobs:register_mob("mobs_mc:creeper", {
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
self.object:remove()
end
end
end,
@ -140,9 +139,6 @@ mobs:register_mob("mobs_mc:creeper_charged", {
pathfinding = 1,
visual = "mesh",
mesh = "mobs_mc_creeper.b3d",
--BOOM
textures = {
{"mobs_mc_creeper.png",
"mobs_mc_creeper_charge.png"},
@ -199,6 +195,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
self.object:remove()
end
end
end,
@ -253,158 +250,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
glow = 3,
})
mobs:spawn_specific(
"mobs_mc:creeper",
"overworld",
"ground",
{
"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,
7,
20,
16500,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)

View File

@ -1 +0,0 @@
mcl_mobs

View File

@ -50,8 +50,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
arrow = "mobs_mc:dragon_fireball",
shoot_interval = 0.5,
shoot_offset = -1.0,
xp_min = 500,
xp_max = 500,
xp_min = 12000,
xp_max = 12000,
animation = {
fly_speed = 8, stand_speed = 8,
stand_start = 0, stand_end = 20,
@ -59,47 +59,15 @@ mobs:register_mob("mobs_mc:enderdragon", {
run_start = 0, run_end = 20,
},
ignores_nametag = true,
do_custom = function(self)
mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple")
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do
local luaentity = obj:get_luaentity()
if luaentity and luaentity.name == "mcl_end:crystal" then
if luaentity.beam then
if luaentity.beam == self.beam then
break
end
else
if self.beam then
self.beam:remove()
end
minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj)
break
end
end
end
if self._portal_pos then
-- migrate old format
if type(self._portal_pos) == "string" then
self._portal_pos = minetest.string_to_pos(self._portal_pos)
end
local portal_center = vector.add(self._portal_pos, vector.new(3, 11, 3))
local pos = self.object:get_pos()
if vector.distance(pos, portal_center) > 50 then
self.object:set_pos(self._last_good_pos or portal_center)
else
self._last_good_pos = pos
end
end
end,
on_die = function(self, pos)
if self._portal_pos then
mcl_portals.spawn_gateway_portal()
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
if self._initial then
mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
end
on_die = function(self, own_pos)
if self._egg_spawn_pos then
local pos = minetest.string_to_pos(self._egg_spawn_pos)
--if minetest.get_node(pos).buildable_to then
minetest.set_node(pos, {name = mobs_mc.items.dragon_egg})
return
--end
end
minetest.add_item(own_pos, mobs_mc.items.dragon_egg)
end,
fire_resistant = true,
})

View File

@ -295,8 +295,7 @@ mobs:register_mob("mobs_mc:enderman", {
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby.
local enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2)
local objs = minetest.get_objects_inside_radius(enderpos, 4)
for n = 1, #objs do
local obj = objs[n]
if obj then
@ -308,7 +307,7 @@ mobs:register_mob("mobs_mc:enderman", {
else
local lua = obj:get_luaentity()
if lua then
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then
if lua.name == "mcl_bows:arrow_entity" then
self:teleport(nil)
end
end
@ -329,44 +328,35 @@ mobs:register_mob("mobs_mc:enderman", {
--end
end
-- Check to see if people are near by enough to look at us.
for _,obj in pairs(minetest.get_connected_players()) do
--check if they are within radius
local player_pos = obj:get_pos()
if player_pos then -- prevent crashing in 1 in a million scenario
local ender_distance = vector.distance(enderpos, player_pos)
if ender_distance <= 64 then
local objs = minetest.get_objects_inside_radius(enderpos, 64)
local obj
for n = 1, #objs do
obj = objs[n]
if obj then
if minetest.is_player(obj) then
-- Check if they are looking at us.
local player_pos = obj:get_pos()
local look_dir_not_normalized = obj:get_look_dir()
local look_dir = vector.normalize(look_dir_not_normalized)
local player_eye_height = obj:get_properties().eye_height
--skip player if they have no data - log it
if not player_eye_height then
minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!")
else
--calculate very quickly the exact location the player is looking
--within the distance between the two "heads" (player and enderman)
local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z)
local look_pos_base = look_pos
local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z)
local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos)
look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player))
--if looking in general head position, turn hostile
if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then
local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod.
-- Cast up to 64 to see if player is looking at enderman.
for n = 1,64,.25 do
local node = minetest.get_node(look_pos)
if node.name ~= "air" then
break
end
if look_pos.x-1<enderpos.x and look_pos.x+1>enderpos.x and look_pos.y-2.89<enderpos.y and look_pos.y-2>enderpos.y and look_pos.z-1<enderpos.z and look_pos.z+1>enderpos.z then
self.provoked = "staring"
self.attack = minetest.get_player_by_name(obj:get_player_name())
break
else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez
else
if self.provoked == "staring" then
self.provoked = "broke_contact"
end
end
end
look_pos.x = look_pos.x + (.25 * look_dir.x)
look_pos.y = look_pos.y + (.25 * look_dir.y)
look_pos.z = look_pos.z + (.25 * look_dir.z)
end
end
end
@ -544,11 +534,9 @@ mobs:register_mob("mobs_mc:enderman", {
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
-- self:teleport(nil)
--else
if pr:next(1, 8) == 8 then --FIXME: real mc rate
self:teleport(hitter)
end
self.attack=hitter
self.state="attack"
self.attack=hitter
self.state="attack"
--end
end
end,
@ -561,189 +549,11 @@ mobs:register_mob("mobs_mc:enderman", {
-- End spawn
mobs:spawn_specific(
"mobs_mc:enderman",
"end",
"ground",
{
"End"
},
0,
minetest.LIGHT_MAX+1,
30,
3000,
12,
mobs_mc.spawn_height.end_min,
mobs_mc.spawn_height.end_max)
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max)
-- Overworld spawn
mobs:spawn_specific(
"mobs_mc:enderman",
"overworld",
"ground",
{
"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,
7,
30,
19000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- Nether spawn (rare)
mobs:spawn_specific(
"mobs_mc:enderman",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
27500,
4,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- spawn eggs
mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)

View File

@ -63,32 +63,10 @@ mobs:register_mob("mobs_mc:ghast", {
makes_footstep_sound = false,
instant_death = true,
fire_resistant = true,
do_custom = function(self)
if self.firing == true then
self.base_texture = {"mobs_mc_ghast_firing.png"}
self.object:set_properties({textures=self.base_texture})
else
self.base_texture = {"mobs_mc_ghast.png"}
self.object:set_properties({textures=self.base_texture})
end
end,
})
mobs:spawn_specific(
"mobs_mc:ghast",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
18000,
2,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- fireball (projectile)
mobs:register_arrow("mobs_mc:fireball", {
@ -96,7 +74,6 @@ mobs:register_arrow("mobs_mc:fireball", {
visual_size = {x = 1, y = 1},
textures = {"mcl_fire_fire_charge.png"},
velocity = 15,
collisionbox = {-.5, -.5, -.5, .5, .5, .5},
hit_player = function(self, player)
if rawget(_G, "armor") and armor.last_damage_types then

View File

@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", {
view_range = 16,
})
-- Spawning disabled due to size issues <- what do you mean? -j4i
-- Spawning disabled due to size issues
-- TODO: Re-enable spawning
-- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18)

View File

@ -157,29 +157,8 @@ local horse = {
self._regentimer = 0
end
-- Some weird human is riding. Buck them off?
if self.driver and not self.tamed and self.buck_off_time <= 0 then
if math.random() < 0.2 then
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
-- TODO bucking animation
else
-- Nah, can't be bothered. Think about it again in one second
self.buck_off_time = 20
end
end
-- Tick the timer for trying to buck the player off
if self.buck_off_time then
if self.driver then
self.buck_off_time = self.buck_off_time - 1
else
-- Player isn't riding anymore so no need to count
self.buck_off_time = nil
end
end
-- if driver present and horse has a saddle allow control of horse
if self.driver and self._saddle then
-- if driver present allow control of horse
if self.driver then
mobs.drive(self, "walk", "stand", false, dtime)
@ -212,49 +191,6 @@ local horse = {
local item = clicker:get_wielded_item()
local iname = item:get_name()
local heal = 0
-- Taming
self.temper = self.temper or (math.random(1,100))
if not self.tamed then
local temper_increase = 0
-- Feeding, intentionally not using mobs:feed_tame because horse taming is
-- different and more complicated
if (iname == mobs_mc.items.sugar) then
temper_increase = 3
elseif (iname == mobs_mc.items.wheat) then
temper_increase = 3
elseif (iname == mobs_mc.items.apple) then
temper_increase = 3
elseif (iname == mobs_mc.items.golden_carrot) then
temper_increase = 5
elseif (iname == mobs_mc.items.golden_apple) then
temper_increase = 10
-- Trying to ride
elseif not self.driver then
self.object:set_properties({stepheight = 1.1})
mobs.attach(self, clicker)
self.buck_off_time = 40 -- TODO how long does it take in minecraft?
if self.temper > 100 then
self.tamed = true -- NOTE taming can only be finished by riding the horse
if not self.owner or self.owner == "" then
self.owner = clicker:get_player_name()
end
end
temper_increase = 5
-- Clicking on the horse while riding ==> unmount
elseif self.driver and self.driver == clicker then
mobs.detach(clicker, {x = 1, y = 0, z = 1})
end
-- If nothing happened temper_increase = 0 and addition does nothing
self.temper = self.temper + temper_increase
return
end
if can_breed(self.name) then
-- Breed horse with golden apple or golden carrot
if (iname == mobs_mc.items.golden_apple) then
@ -266,8 +202,7 @@ local horse = {
return
end
end
-- Feed with anything else
-- TODO heal amounts don't work
-- Feed/tame with anything else
if (iname == mobs_mc.items.sugar) then
heal = 1
elseif (iname == mobs_mc.items.wheat) then
@ -277,7 +212,7 @@ local horse = {
elseif (iname == mobs_mc.items.hay_bale) then
heal = 20
end
if heal > 0 and mobs:feed_tame(self, clicker, heal, false, false) then
if heal > 0 and mobs:feed_tame(self, clicker, heal, false, true) then
return
end
@ -510,56 +445,8 @@ mobs:register_mob("mobs_mc:mule", mule)
--===========================
--Spawn Function
mobs:spawn_specific(
"mobs_mc:horse",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:donkey",
"overworld",
"ground",
{
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)

View File

@ -217,25 +217,7 @@ mobs:register_mob("mobs_mc:llama", {
})
--spawn
mobs:spawn_specific(
"mobs_mc:llama",
"overworld",
"ground",
{
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
5,
mobs_mc.spawn_height.water+15,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)

View File

@ -152,25 +152,6 @@ mobs:register_mob("mobs_mc:cat", cat)
local base_spawn_chance = 5000
-- Spawn ocelot
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i
mobs:spawn_specific(
"mobs_mc:ocelot",
"overworld",
"ground",
{
"Jungle",
"JungleEdgeM",
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
5,
mobs_mc.spawn_height.water+15,
mobs_mc.spawn_height.overworld_max)
--[[
mobs:spawn({
name = "mobs_mc:ocelot",
nodes = mobs_mc.spawn.jungle,
@ -182,8 +163,8 @@ mobs:spawn({
min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
max_height = mobs_mc.spawn_height.overworld_max,
on_spawn = function(self, pos)
Note: Minecraft has a 1/3 spawn failure rate.
In this mod it is emulated by reducing the spawn rate accordingly (see above).
--[[ Note: Minecraft has a 1/3 spawn failure rate.
In this mod it is emulated by reducing the spawn rate accordingly (see above). ]]
-- 1/7 chance to spawn 2 ocelot kittens
if pr:next(1,7) == 1 then
@ -226,7 +207,6 @@ mobs:spawn({
end
end,
})
]]--
-- spawn eggs
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture

View File

@ -90,24 +90,8 @@ mobs:register_mob("mobs_mc:parrot", {
})
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
mobs:spawn_specific(
"mobs_mc:parrot",
"overworld",
"ground",
{
"Jungle",
"JungleEdgeM",
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
7,
30000,
1,
mobs_mc.spawn_height.water+7,
mobs_mc.spawn_height.overworld_max)
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome*
mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)

View File

@ -182,35 +182,7 @@ mobs:register_mob("mobs_mc:pig", {
end,
})
mobs:spawn_specific(
"mobs_mc:pig",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
15000,
8,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)

View File

@ -67,23 +67,7 @@ mobs:register_mob("mobs_mc:polar_bear", {
})
mobs:spawn_specific(
"mobs_mc:polar_bear",
"overworld",
"ground",
{
"ColdTaiga",
"IcePlainsSpikes",
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
minetest.LIGHT_MAX+1,
30,
7000,
3,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn egg
mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)

View File

@ -107,39 +107,8 @@ end
mobs:register_mob("mobs_mc:killer_bunny", killer_bunny)
-- Mob spawning rules.
-- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out
-- Different skins depending on spawn location
mobs:spawn_specific(
"mobs_mc:rabbit",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
15000,
8,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
--[[
local spawn = {
name = "mobs_mc:rabbit",
neighbors = {"air"},
@ -196,7 +165,6 @@ spawn_grass.on_spawn = function(self, pos)
self.object:set_properties({textures = self.base_texture})
end
mobs:spawn(spawn_grass)
]]--
-- Spawn egg
mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)

View File

@ -303,35 +303,7 @@ mobs:register_mob("mobs_mc:sheep", {
end
end,
})
mobs:spawn_specific(
"mobs_mc:sheep",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
3,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)

View File

@ -81,17 +81,4 @@ mobs:register_arrow("mobs_mc:shulkerbullet", {
mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
mobs:spawn_specific(
"mobs_mc:shulker",
"end",
"ground",
{
"End"
},
0,
minetest.LIGHT_MAX+1,
30,
5000,
2,
mobs_mc.spawn_height.end_min,
mobs_mc.spawn_height.end_max)
mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max)

View File

@ -139,195 +139,13 @@ table.insert(stray.drops, {
mobs:register_mob("mobs_mc:stray", stray)
-- Overworld spawn
mobs:spawn_specific(
"mobs_mc:skeleton",
"overworld",
"ground",
{
"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,
7,
20,
17000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- Nether spawn
mobs:spawn_specific(
"mobs_mc:skeleton",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
10000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- Stray spawn
-- TODO: Spawn directly under the sky
mobs:spawn_specific(
"mobs_mc:stray",
"overworld",
"ground",
{
"ColdTaiga",
"IcePlainsSpikes",
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
7,
20,
19000,
2,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max)
-- spawn eggs

View File

@ -94,20 +94,7 @@ mobs:register_mob("mobs_mc:witherskeleton", {
})
--spawn
mobs:spawn_specific(
"mobs_mc:witherskeleton",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
5000,
5,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- spawn eggs
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)

View File

@ -51,6 +51,7 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
end
end, children, self.attack)
end
return true
end
end
@ -157,137 +158,9 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny)
local smin = mobs_mc.spawn_height.overworld_min
local smax = mobs_mc.spawn_height.water - 23
mobs:spawn_specific(
"mobs_mc:slime_tiny",
"overworld",
"ground",
{
"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,
12000,
4,
smin,
smax)
mobs:spawn_specific(
"mobs_mc:slime_small",
"overworld",
"ground",
{
"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,
8500,
4,
smin,
smax)
mobs:spawn_specific(
"mobs_mc:slime_big",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
10000,
4,
smin,
smax)
mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax)
mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax)
mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax)
-- Magma cube
local magma_cube_big = {
@ -400,55 +273,13 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
local mmin = mobs_mc.spawn_height.nether_min
local mmax = mobs_mc.spawn_height.nether_max
mobs:spawn_specific(
"mobs_mc:magma_cube_tiny",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mmin,
mmax)
mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax)
mobs:spawn_specific(
"mobs_mc:magma_cube_small",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
15500,
4,
mmin,
mmax)
mobs:spawn_specific(
"mobs_mc:magma_cube_big",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
16000,
4,
mmin,
mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
-- spawn eggs

View File

@ -87,158 +87,7 @@ cave_spider.sounds.base_pitch = 1.25
mobs:register_mob("mobs_mc:cave_spider", cave_spider)
mobs:spawn_specific(
"mobs_mc:spider",
"overworld",
"ground",
{
"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,
7,
30,
17000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0)

View File

@ -62,158 +62,7 @@ mobs:register_mob("mobs_mc:squid", {
local water = mobs_mc.spawn_height.water
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
mobs:spawn_specific(
"mobs_mc:squid",
"overworld",
"water",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
5500,
3,
water-16,
water+1)
mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water)
-- spawn eggs
mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1074,35 +1074,7 @@ mobs:register_mob("mobs_mc:villager", {
mobs:spawn_specific(
"mobs_mc:villager",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
20,
4,
mobs_mc.spawn_height.water+1,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0)

View File

@ -146,99 +146,8 @@ mobs:register_mob("mobs_mc:villager_zombie", {
harmed_by_heal = true,
})
mobs:spawn_specific(
"mobs_mc:villager_zombie",
"overworld",
"ground",
{
"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",
"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",
},
0,
7,
30,
4090,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
--mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0)

View File

@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:potion_arrow", {
end
})
-- TODO: Spawn when witch works properly <- eventually -j4i
-- TODO: Spawn when witch works properly
--mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max)
-- spawn eggs

View File

@ -73,7 +73,6 @@ mobs:register_mob("mobs_mc:wither", {
self.object:set_properties({textures={self.base_texture}})
self.armor = {undead = 80, fleshy = 80}
end
mcl_bossbars.update_boss(self, "Wither", "dark_purple")
end,
on_spawn = function(self)
minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64})
@ -116,4 +115,4 @@ mobs:register_arrow("mobs_mc:wither_skull", {
--Spawn egg
mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true)
mcl_wip.register_wip_item("mobs_mc:wither")
mcl_wip.register_wip_item("mobs_mc:wither")

View File

@ -232,34 +232,6 @@ end
mobs:register_mob("mobs_mc:dog", dog)
-- Spawn
mobs:spawn_specific(
"mobs_mc:wolf",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
9000,
7,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max)
mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0)

View File

@ -135,227 +135,11 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk)
-- Spawning
mobs:spawn_specific(
"mobs_mc:zombie",
"overworld",
"ground",
{
"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",
"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",
},
0,
7,
30,
6000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific(
"mobs_mc:baby_zombie",
"overworld",
"ground",
{
"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",
"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",
},
0,
7,
30,
60000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:husk",
"overworld",
"ground",
{
"Desert",
"SavannaM",
"Savanna",
"Savanna_beach",
},
0,
7,
30,
6500,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:baby_husk",
"overworld",
"ground",
{
"Desert",
"SavannaM",
"Savanna",
"Savanna_beach",
},
0,
7,
30,
65000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- Spawn eggs
mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0)

View File

@ -111,38 +111,12 @@ baby_pigman.child = 1
mobs:register_mob("mobs_mc:baby_pigman", baby_pigman)
-- Regular spawning in the Nether
mobs:spawn_specific(
"mobs_mc:pigman",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
6000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific(
"mobs_mc:baby_pigman",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
100000,
4,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max)
-- Spawning in Nether portals in the Overworld
--mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0)

View File

@ -17,7 +17,7 @@ To give you a *very* brief overview over this API, here is the basic workflow on
In order to use this API, you should be aware of a few basic rules in order to understand it:
* A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%.
* The current value must always be equal to or smaller then the maximum
* The current value must always be equal to or smaller then the maximum
* Both current value and maximum must not be smaller than 0
* Both current value and maximum must be real numbers. So no NaN, infinity, etc.
* The HUD bar will be hidden if the maximum equals 0. This is intentional.
@ -45,7 +45,7 @@ a vertical gradient.
### Icon
A 16×16 image shown left of the HUD bar. This is optional.
### `hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)`
### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)`
This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden
and unhidden on a per-player basis.
Note this does not yet display the HUD bar.
@ -63,7 +63,6 @@ for more information.
* `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section).
* `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used.
* `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode.
* `direction`: Either left to right(0), or right to left(1).
* `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value
* `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value
* `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it.

View File

@ -20,9 +20,9 @@ if hb.settings.bar_type == "progress_bar" then
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15)
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86)
else
hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -258)
hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265)
hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90)
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 16)
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25)
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90)
end
-- Modified in MCL2!

View File

@ -124,7 +124,7 @@ function hb.get_hudbar_position_index(identifier)
end
end
function hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)
function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)
minetest.log("action", "hb.register_hudbar: "..tostring(identifier))
local hudtable = {}
local pos, offset
@ -133,33 +133,30 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
if hb.settings.alignment_pattern == "stack_up" then
pos = hb.settings.pos_left
offset = {
x = direction == 0 and hb.settings.start_offset_left.x or -hb.settings.start_offset_right.x,
x = hb.settings.start_offset_left.x,
y = hb.settings.start_offset_left.y - hb.settings.vmargin * index
}
elseif hb.settings.alignment_pattern == "stack_down" then
pos = hb.settings.pos_left
offset = {
x = direction == 0 and hb.settings.start_offset_right.x or -hb.settings.start_offset_left.x,
x = hb.settings.start_offset_left.x,
y = hb.settings.start_offset_left.y + hb.settings.vmargin * index
}
else -- zigzag
else
if index % 2 == 0 then
pos = hb.settings.pos_left
offset = {
-- -(24+18) = -42. using linear eq, -42 = -258m - 24.
x = direction == 0 and hb.settings.start_offset_left.x or (-42+24)/(-258.0) * hb.settings.start_offset_left.x - 24,
x = hb.settings.start_offset_left.x,
y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2)
}
else
pos = hb.settings.pos_right
offset = {
-- 24*10+30 - 24 = 234. using linear eq, 234 = 16m - 24.
x = direction == 0 and hb.settings.start_offset_right.x or (234+24)/(16) * hb.settings.start_offset_right.x - 24,
x = hb.settings.start_offset_right.x,
y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2)
}
end
end
if format_string == nil then
format_string = N("@1: @2/@3")
end
@ -184,7 +181,6 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
local state = {}
local name = player:get_player_name()
local bgscale, iconscale, text, barnumber, bgiconnumber
if start_max == 0 or start_hidden then
bgscale = { x=0, y=0 }
else
@ -201,7 +197,6 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
bgiconnumber = hb.settings.statbar_length
text = make_label(format_string, format_string_config, label, start_value, start_max)
end
if hb.settings.bar_type == "progress_bar" then
ids.bg = player:hud_add({
hud_elem_type = "image",
@ -224,7 +219,6 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
})
end
end
local bar_image, bgicon, bar_size
if hb.settings.bar_type == "progress_bar" then
bar_image = textures.bar
@ -240,12 +234,10 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
bgicon = textures.bgicon
bar_size = {x=24, y=24}
end
local text2
if hb.settings.bar_type == "statbar_modern" then
text2 = bgicon
end
ids.bar = player:hud_add({
hud_elem_type = "statbar",
position = pos,
@ -255,7 +247,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
item = bgiconnumber,
alignment = {x=-1,y=-1},
offset = offset,
direction = direction,
direction = 0,
size = bar_size,
z_index = 1,
})
@ -266,7 +258,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
text = text,
alignment = {x=1,y=1},
number = text_color,
direction = direction,
direction = 0,
offset = { x = offset.x + 2, y = offset.y - 1},
z_index = 2,
})
@ -306,7 +298,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction,
hudtable.default_start_max = default_start_max
hb.hudbars_count= hb.hudbars_count + 1
hb.hudtables[identifier] = hudtable
end
@ -367,7 +359,6 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon
if new_text_color ~= nil then
player:hud_change(hudtable.hudids[name].text, "number", new_text_color)
end
else
if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then
player:hud_change(hudtable.hudids[name].bar, "text", new_icon)
@ -483,8 +474,8 @@ end
--register built-in HUD bars
if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 0, 20, 20, false)
hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 1, 10, 10, true)
hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false)
hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true)
end
local function hide_builtin(player)
@ -529,7 +520,7 @@ local function update_hud(player, has_damage)
--air
local breath_max = player:get_properties().breath_max
local breath = player:get_breath()
if breath >= breath_max and hb.settings.autohide_breath == true then
hb.hide_hudbar(player, "breath")
else

View File

@ -1,187 +0,0 @@
mcl_bossbars = {
bars = {},
huds = {},
static = {},
colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"},
max_bars = tonumber(minetest.settings:get("max_bossbars")) or 4
}
function mcl_bossbars.recalculate_colors()
local sorted = {}
local colors = mcl_bossbars.colors
local color_count = #colors
local frame_count = color_count * 2
for i, color in ipairs(colors) do
local idx = i * 2 - 1
local image = "mcl_bossbars.png"
.. "^[transformR270"
.. "^[verticalframe:" .. frame_count .. ":" .. (idx - 1)
.. "^(mcl_bossbars_empty.png"
.. "^[lowpart:%d:mcl_bossbars.png"
.. "^[transformR270"
.. "^[verticalframe:" .. frame_count .. ":" .. idx .. ")"
local _, hex = mcl_util.get_color(color)
sorted[color] = {
image = image,
hex = hex,
}
end
mcl_bossbars.colors_sorted = sorted
end
local function get_color_info(color, percentage)
local cdef = mcl_bossbars.colors_sorted[color]
return cdef.hex, string.format(cdef.image, percentage)
end
local last_id = 0
function mcl_bossbars.add_bar(player, def, dynamic, priority)
local name = player:get_player_name()
local bars = mcl_bossbars.bars[name]
local bar = {text = def.text, priority = priority or 0}
bar.color, bar.image = get_color_info(def.color, def.percentage)
if dynamic then
for _, other in pairs(bars) do
if not other.id and other.color == bar.color and (other.original_text or other.text) == bar.text and other.image == bar.image then
if not other.count then
other.count = 1
other.original_text = other.text
end
other.count = other.count + 1
other.text = other.original_text .. " x" .. other.count
return
end
end
end
table.insert(bars, bar)
if not dynamic then
bar.raw_color = def.color
bar.id = last_id + 1
last_id = bar.id
mcl_bossbars.static[bar.id] = bar
return id
end
end
function mcl_bossbars.remove_bar(id)
mcl_bossbars.static[id].bar.static = false
mcl_bossbars.static[id] = nil
end
function mcl_bossbars.update_bar(id, def, priority)
local old = mcl_bossbars.static[id]
old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage)
old.text = def.text or old.text
old.priority = priority or old.priority
end
function mcl_bossbars.update_boss(luaentity, name, color)
local object = luaentity.object
local bardef = {
text = luaentity.nametag,
percentage = math.floor(luaentity.health / luaentity.hp_max * 100),
color = color,
}
if not bardef.text or bardef.text == "" then
bardef.text = name
end
local pos = object:get_pos()
for _, player in pairs(minetest.get_connected_players()) do
local d = vector.distance(pos, player:get_pos())
if d <= 80 then
mcl_bossbars.add_bar(player, bardef, true, d)
end
end
end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
mcl_bossbars.huds[name] = {}
mcl_bossbars.bars[name] = {}
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
mcl_bossbars.huds[name] = nil
for _, bar in pairs(mcl_bossbars.bars[name]) do
if bar.id then
mcl_bossbars.static[bar.id] = nil
end
end
mcl_bossbars.bars[name] = nil
end)
minetest.register_globalstep(function()
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local bars = mcl_bossbars.bars[name]
local huds = mcl_bossbars.huds[name]
table.sort(bars, function(a, b) return a.priority < b.priority end)
local huds_new = {}
local bars_new = {}
local i = 0
while #huds > 0 or #bars > 0 do
local bar = table.remove(bars, 1)
local hud = table.remove(huds, 1)
if bar and bar.id then
table.insert(bars_new, bar)
end
if bar and not hud then
if i < mcl_bossbars.max_bars then
hud = {
color = bar.color,
image = bar.image,
text = bar.text,
text_id = player:hud_add({
hud_elem_type = "text",
text = bar.text,
number = bar.color,
position = {x = 0.5, y = 0},
alignment = {x = 0, y = 1},
offset = {x = 0, y = i * 40},
}),
image_id = player:hud_add({
hud_elem_type = "image",
text = bar.image,
position = {x = 0.5, y = 0},
alignment = {x = 0, y = 1},
offset = {x = 0, y = i * 40 + 25},
scale = {x = 3, y = 3},
}),
}
end
elseif hud and not bar then
player:hud_remove(hud.text_id)
player:hud_remove(hud.image_id)
hud = nil
else
if bar.text ~= hud.text then
player:hud_change(hud.text_id, "text", bar.text)
hud.text = bar.text
end
if bar.color ~= hud.color then
player:hud_change(hud.text_id, "number", bar.color)
hud.color = bar.color
end
if bar.image ~= hud.image then
player:hud_change(hud.image_id, "text", bar.image)
hud.image = bar.image
end
end
table.insert(huds_new, hud)
i = i + 1
end
mcl_bossbars.huds[name] = huds_new
mcl_bossbars.bars[name] = bars_new
end
end)
mcl_bossbars.recalculate_colors()

View File

@ -1,4 +0,0 @@
name = mcl_bossbars
author = Fleckenstein
description = Show enderdragon & wither boss bars. Also allows custom bars.
depends = mcl_util, mcl_colors

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,209 +0,0 @@
mcl_credits = {
players = {},
}
mcl_credits.description = "A faithful Open Source clone of Minecraft"
-- Sub-lists are sorted by number of commits, but the list should not be rearranged (-> new contributors are just added at the end of the list)
mcl_credits.people = {
{"Creator of MineClone", 0x0A9400, {
"davedevils",
}},
{"Creator of MineClone2", 0xFBF837, {
"Wuzzy",
}},
{"Maintainers", 0xFF51D5, {
"Fleckenstein",
"kay27",
"oilboi",
}},
{"Developers", 0xF84355, {
"bzoss",
"AFCMS",
"epCode",
"ryvnf",
"iliekprogrammar",
"MysticTempest",
"Rootyjr",
"Nicu",
"aligator",
}},
{"Contributors", 0x52FF00, {
"Code-Sploit",
"Laurent Rocher",
"HimbeerserverDE",
"TechDudie",
"Alexander Minges",
"ArTee3",
"ZeDique la Ruleta",
"pitchum",
"wuniversales",
"Bu-Gee",
"David McMackins II",
"Nicholas Niro",
"Wouters Dorian",
"Blue Blancmange",
"Jared Moody",
"Li0n",
"Midgard",
"NO11",
"Saku Laesvuori",
"Yukitty",
"ZedekThePD",
"aldum",
"dBeans",
"nickolas360",
"yutyo",
"ztianyang",
}},
{"MineClone5", 0xA60014, {
"kay27",
"Debiankaios",
"epCode",
"NO11",
"j45",
}},
{"3D Models", 0x0019FF, {
"22i",
"tobyplowy",
"epCode",
}},
{"Textures", 0xFF9705, {
"XSSheep",
"Wuzzy",
"kingoscargames",
"leorockway",
"xMrVizzy",
"yutyo"
}},
{"Translations", 0x00FF60, {
"Wuzzy",
"Rocher Laurent",
"wuniversales",
"kay27",
"pitchum",
}},
}
local function add_hud_element(def, huds, y)
def.alignment = {x = 0, y = 0}
def.position = {x = 0.5, y = 0}
def.offset = {x = 0, y = y}
def.z_index = 1001
local id = huds.player:hud_add(def)
table.insert(huds.ids, id)
huds.moving[id] = y
return id
end
function mcl_credits.show(player)
local name = player:get_player_name()
if mcl_credits.players[name] then
return
end
local huds = {
new = true, -- workaround for MT < 5.5 (sending hud_add and hud_remove in the same tick)
player = player,
moving = {},
ids = {
player:hud_add({
hud_elem_type = "image",
text = "menu_bg.png",
position = {x = 0, y = 0},
alignment = {x = 1, y = 1},
scale = {x = -100, y = -100},
z_index = 1000,
}),
player:hud_add({
hud_elem_type = "text",
text = "Sneak to skip",
position = {x = 1, y = 1},
alignment = {x = -1, y = -1},
offset = {x = -5, y = -5},
z_index = 1001,
number = 0xFFFFFF,
})
},
}
add_hud_element({
hud_elem_type = "image",
text = "mineclone2_logo.png",
scale = {x = 1, y = 1},
}, huds, 300, 0)
add_hud_element({
hud_elem_type = "text",
text = mcl_credits.description,
number = 0x757575,
scale = {x = 5, y = 5},
}, huds, 350, 0)
local y = 450
for _, group in ipairs(mcl_credits.people) do
add_hud_element({
hud_elem_type = "text",
text = group[1],
number = group[2],
scale = {x = 3, y = 3},
}, huds, y, 0)
y = y + 25
for _, name in ipairs(group[3]) do
y = y + 25
add_hud_element({
hud_elem_type = "text",
text = name,
number = 0xFFFFFF,
scale = {x = 1, y = 1},
}, huds, y, 0)
end
y = y + 200
end
huds.icon = add_hud_element({
hud_elem_type = "image",
text = "mineclone2_icon.png",
scale = {x = 1, y = 1},
}, huds, y)
mcl_credits.players[name] = huds
end
function mcl_credits.hide(player)
local name = player:get_player_name()
local huds = mcl_credits.players[name]
if huds then
for _, id in pairs(huds.ids) do
player:hud_remove(id)
end
end
mcl_credits.players[name] = nil
end
minetest.register_on_leaveplayer(function(player)
mcl_credits.players[player:get_player_name()] = nil
end)
minetest.register_globalstep(function(dtime)
for _, huds in pairs(mcl_credits.players) do
local player = huds.player
if not huds.new and player:get_player_control().sneak then
mcl_credits.hide(player)
else
local moving = {}
local any
for id, y in pairs(huds.moving) do
y = y - 1
if y > -100 then
if id == huds.icon then
y = math.max(400, y)
else
any = true
end
player:hud_change(id, "offset", {x = 0, y = y})
moving[id] = y
end
end
if not any then
mcl_credits.hide(player)
end
huds.moving = moving
end
huds.new = false
end
end)

View File

@ -1,3 +0,0 @@
name = mcl_credits
author = Fleckenstein
description = Show a HUD containing the credits

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

View File

@ -57,7 +57,7 @@ local function custom_hud(player)
end
--register and define armor HUD bar
hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide)
hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 20, mcl_hbarmor.autohide)
function mcl_hbarmor.get_armor(player)
if not player or not armor.def then

View File

@ -47,34 +47,28 @@
-- mesecon.rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction
local equals = vector.equals
local get_node_force = mesecon.get_node_force
local invertRule = mesecon.invertRule
local copy, insert = table.copy, table.insert
local registered_nodes = minetest.registered_nodes
-- General
function mesecon.get_effector(nodename)
if registered_nodes[nodename]
and registered_nodes[nodename].mesecons
and registered_nodes[nodename].mesecons.effector then
return registered_nodes[nodename].mesecons.effector
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.effector then
return minetest.registered_nodes[nodename].mesecons.effector
end
end
function mesecon.get_receptor(nodename)
if registered_nodes[nodename]
and registered_nodes[nodename].mesecons
and registered_nodes[nodename].mesecons.receptor then
return registered_nodes[nodename].mesecons.receptor
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.receptor then
return minetest.registered_nodes[nodename].mesecons.receptor
end
end
function mesecon.get_conductor(nodename)
if registered_nodes[nodename]
and registered_nodes[nodename].mesecons
and registered_nodes[nodename].mesecons.conductor then
return registered_nodes[nodename].mesecons.conductor
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.conductor then
return minetest.registered_nodes[nodename].mesecons.conductor
end
end
@ -109,14 +103,13 @@ end
-- Receptors
-- Nodes that can power mesecons
local function is_receptor_on(nodename)
function mesecon.is_receptor_on(nodename)
local receptor = mesecon.get_receptor(nodename)
if receptor and receptor.state == mesecon.state.on then
return true
end
return false
end
mesecon.is_receptor_on = is_receptor_on
function mesecon.is_receptor_off(nodename)
local receptor = mesecon.get_receptor(nodename)
@ -134,7 +127,7 @@ function mesecon.is_receptor(nodename)
return false
end
local function receptor_get_rules(node)
function mesecon.receptor_get_rules(node)
local receptor = mesecon.get_receptor(node.name)
if receptor then
local rules = receptor.rules
@ -147,7 +140,6 @@ local function receptor_get_rules(node)
return mesecon.rules.default
end
mesecon.receptor_get_rules = receptor_get_rules
-- Effectors
-- Nodes that can be powered by mesecons
@ -194,7 +186,7 @@ end
-- Activation:
mesecon.queue:add_function("activate", function (pos, rulename)
local node = get_node_force(pos)
local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name)
@ -206,7 +198,7 @@ end)
function mesecon.activate(pos, node, rulename, depth)
if rulename == nil then
for _,rule in pairs(mesecon.effector_get_rules(node)) do
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.activate(pos, node, rule, depth + 1)
end
return
@ -217,7 +209,7 @@ end
-- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = get_node_force(pos)
local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name)
@ -229,7 +221,7 @@ end)
function mesecon.deactivate(pos, node, rulename, depth)
if rulename == nil then
for _,rule in pairs(mesecon.effector_get_rules(node)) do
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.deactivate(pos, node, rule, depth + 1)
end
return
@ -240,7 +232,7 @@ end
-- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = get_node_force(pos)
local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name)
@ -252,7 +244,7 @@ end)
function mesecon.changesignal(pos, node, rulename, newstate, depth)
if rulename == nil then
for _,rule in pairs(mesecon.effector_get_rules(node)) do
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
end
return
@ -364,15 +356,15 @@ end
-- some more general high-level stuff
function mesecon.is_power_on(pos, rulename)
local node = get_node_force(pos)
if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then
local node = mesecon.get_node_force(pos)
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
return true
end
return false
end
function mesecon.is_power_off(pos, rulename)
local node = get_node_force(pos)
local node = mesecon.get_node_force(pos)
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
return true
end
@ -389,7 +381,7 @@ function mesecon.turnon(pos, link)
local depth = 1
while frontiers[1] do
local f = table.remove(frontiers, 1)
local node = get_node_force(f.pos)
local node = mesecon.get_node_force(f.pos)
if not node then
-- Area does not exist; do nothing
@ -397,10 +389,10 @@ function mesecon.turnon(pos, link)
local rules = mesecon.conductor_get_rules(node)
-- Call turnon on neighbors
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r)
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
insert(frontiers, {pos = np, link = l})
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
table.insert(frontiers, {pos = np, link = l})
end
end
@ -414,12 +406,12 @@ function mesecon.turnon(pos, link)
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnon on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = vector.add(f.pos, r)
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = copy(l)
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = table.copy(l)
nlink.spread = false
insert(frontiers, {pos = np, link = nlink})
table.insert(frontiers, {pos = np, link = nlink})
end
end
end
@ -451,33 +443,33 @@ function mesecon.turnoff(pos, link)
local depth = 1
while frontiers[1] do
local f = table.remove(frontiers, 1)
local node = get_node_force(f.pos)
local node = mesecon.get_node_force(f.pos)
if not node then
-- No-op
elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r)
-- Check if an onstate receptor is connected. If that is the case,
-- abort this turnoff process by returning false. `receptor_off` will
-- discard all the changes that we made in the voxelmanip:
for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
if is_receptor_on(get_node_force(np).name) then
for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then
return false
end
end
-- Call turnoff on neighbors
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
insert(frontiers, {pos = np, link = l})
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
table.insert(frontiers, {pos = np, link = l})
end
end
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
elseif mesecon.is_effector(node.name) then
insert(signals, {
table.insert(signals, {
pos = f.pos,
node = node,
link = f.link,
@ -488,22 +480,21 @@ function mesecon.turnoff(pos, link)
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnoff on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work
local fpos = f.pos
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z}
local n = get_node_force(np)
if n and is_receptor_on(n.name) then
local receptorrules = receptor_get_rules(n)
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = vector.add(f.pos, r)
local n = mesecon.get_node_force(np)
if mesecon.is_receptor_on(n.name) then
local receptorrules = mesecon.receptor_get_rules(n)
for _, rr in pairs(receptorrules) do
if rr.spread and equals(invertRule(rr), r) then
if rr.spread and vector.equals(mesecon.invertRule(rr), r) then
return false
end
end
end
for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do
local nlink = copy(l)
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = table.copy(l)
nlink.spread = false
insert(frontiers, {pos = np, link = nlink})
table.insert(frontiers, {pos = np, link = nlink})
end
end
end
@ -511,7 +502,7 @@ function mesecon.turnoff(pos, link)
depth = depth + 1
end
for _, sig in pairs(signals) do
for _, sig in ipairs(signals) do
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
@ -525,19 +516,19 @@ end
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
function mesecon.rules_link_rule_all(output, rule)
local input = vector.add(output, rule)
local inputnode = get_node_force(input)
local inputnode = mesecon.get_node_force(input)
local inputrules = mesecon.get_any_inputrules(inputnode)
if not inputrules then
return {}
end
local rules = {}
for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if equals(vector.add(input, inputrule), output) then
local newrule = copy(inputrule)
if vector.equals(vector.add(input, inputrule), output) then
local newrule = table.copy(inputrule)
newrule.spread = rule.spread
insert(rules, newrule)
table.insert(rules, newrule)
end
end
@ -548,19 +539,19 @@ end
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
function mesecon.rules_link_rule_all_inverted(input, rule)
local output = vector.add(input, rule)
local outputnode = get_node_force(output)
local outputnode = mesecon.get_node_force(output)
local outputrules = mesecon.get_any_outputrules(outputnode)
if not outputrules then
return {}
end
local rules = {}
for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do
if equals(vector.add(output, outputrule), input) then
local newrule = copy(outputrule)
newrule = invertRule(newrule)
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if vector.equals(vector.add(output, outputrule), input) then
local newrule = table.copy(outputrule)
newrule = mesecon.invertRule(newrule)
newrule.spread = rule.spread
insert(rules, newrule)
table.insert(rules, newrule)
end
end
return rules
@ -571,7 +562,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
if depth > 1 then
return false, false
end
local node = get_node_force(pos)
local node = mesecon.get_node_force(pos)
local rules = mesecon.get_any_inputrules(node)
if not rules then
return false, false
@ -587,23 +578,23 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
local spread = false
for _, rname in pairs(rulenames) do
for _, rname in ipairs(rulenames) do
local np = vector.add(pos, rname)
local nn = get_node_force(np)
if (mesecon.is_conductor_on (nn, invertRule(rname))
or is_receptor_on (nn.name)) then
if not equals(home_pos, np) then
local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then
if not vector.equals(home_pos, np) then
local rulez = mesecon.get_any_outputrules(nn)
local spread_tmp = false
for r=1, #rulez do
if equals(invertRule(rname), rulez[r]) then
if vector.equals(mesecon.invertRule(rname), rulez[r]) then
if rulez[r].spread then
spread_tmp = true
end
end
end
if depth == 0 or spread_tmp then
insert(sourcepos, np)
table.insert(sourcepos, np)
if spread_tmp then
spread = true
end
@ -621,7 +612,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
local spread = false
if not rule then
for _, rule in pairs(mesecon.flattenrules(rules)) do
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local spread_temp
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)

View File

@ -133,7 +133,7 @@ S("The speed and damage of the arrow increases the longer you charge. The regula
_doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."),
_doc_items_durability = BOW_DURABILITY,
inventory_image = "mcl_bows_bow.png",
wield_scale = mcl_vars.tool_wield_scale,
wield_scale = { x = 1.8, y = 1.8, z = 1 },
stack_max = 1,
range = 4,
-- Trick to disable digging as well
@ -198,7 +198,7 @@ for level=0, 2 do
description = S("Bow"),
_doc_items_create_entry = false,
inventory_image = "mcl_bows_bow_"..level..".png",
wield_scale = mcl_vars.tool_wield_scale,
wield_scale = { x = 1.8, y = 1.8, z = 1 },
stack_max = 1,
range = 0, -- Pointing range to 0 to prevent punching with bow :D
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1},

View File

@ -1,6 +1,6 @@
name = mcl_bows
author = Arcelmi
description = This mod adds bows and arrows for MineClone 2.
depends = controls, mcl_particles, mcl_enchanting, mcl_init
depends = controls, mcl_particles, mcl_enchanting
optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button

View File

@ -212,46 +212,21 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", {
end
end
minetest.add_node(pointed_thing.under, {name="air"})
minetest.set_node(pointed_thing.under, {name="air"})
sound_take(nn, pointed_thing.under)
if mod_doc and doc.entry_exists("nodes", nn) then
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", nn)
end
elseif nn == "mcl_cauldrons:cauldron_3" then
-- Take water out of full cauldron
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
if not minetest.is_creative_enabled(user:get_player_name()) then
new_bucket = ItemStack("mcl_buckets:bucket_water")
end
sound_take("mcl_core:water_source", pointed_thing.under)
elseif nn == "mcl_cauldrons:cauldron_3r" then
-- Take river water out of full cauldron
minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"})
if not minetest.is_creative_enabled(user:get_player_name()) then
new_bucket = ItemStack("mcl_buckets:bucket_river_water")
end
sound_take("mclx_core:river_water_source", pointed_thing.under)
elseif minetest.get_item_group(nn, "cauldron") then
new_bucket = mcl_cauldrons.take_cauldron(pointed_thing.under, new_bucket, user)
end
-- Add liquid bucket and put it into inventory, if possible.
-- Drop new bucket otherwise.
if new_bucket then
if itemstack:get_count() == 1 then
return new_bucket
else
local inv = user:get_inventory()
if inv:room_for_item("main", new_bucket) then
inv:add_item("main", new_bucket)
else
minetest.add_item(user:get_pos(), new_bucket)
end
if not minetest.is_creative_enabled(user:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
if minetest.is_creative_enabled(user:get_player_name()) then --TODO
itemstack:take_item()
end
end,
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)

View File

@ -1,6 +1,6 @@
name = mcl_buckets
author = Kahrl
description =
depends = mcl_worlds
depends = mcl_worlds, mcl_cauldrons
optional_depends = mcl_core, mclx_core, doc

View File

@ -61,7 +61,7 @@ if mod_mcl_core then
if minetest.get_item_group(nn, "cauldron") ~= 0 then
-- Put water into cauldron
if nn ~= "mcl_cauldrons:cauldron_3" then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"})
mcl_cauldrons.set_cauldron_level(pos, "water", 3)
end
sound_place("mcl_core:water_source", pos)
return false
@ -104,7 +104,7 @@ if mod_mclx_core then
if minetest.get_item_group(nn, "cauldron") ~= 0 then
-- Put water into cauldron
if nn ~= "mcl_cauldrons:cauldron_3r" then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"})
mcl_cauldrons.set_cauldron(pos, "river_water", 3)
end
sound_place("mcl_core:water_source", pos)
return false

View File

@ -0,0 +1,28 @@
# mcl_cauldrons
This mod add an API to add cauldrons to mcl.
## mcl_cauldrons.is_cauldron(name)
return true if name is cauldron, false overwise.
## mcl_cauldrons.get_cauldron_string(type, level)
return itemstring of cauldron with <type> and <level>
e.g: `mcl_cauldrons.get_cauldron_string("water", 1) --return itemstring of a water cauldron with 1 level of water`
## mcl_cauldrons.take_cauldron(pos, itemstack, user, sounds)
empty cauldron at `pos`
return `bucket` field of the cauldron def if user is player, itemstack overwise.
* pos: position of the cauldron
* itemstack: will be return if `bucket` field isn't defined in cauldron def or user is nil or not player.
* user: player who takes cauldron
* sounds: sounds table. If not nil, dug sound will be played.
## mcl_cauldrons.register_cauldron_type(def)
def can have these fields:
* name: name of the liquid e.g: "water"
* bucket: string of the bucket item. can be nil. e.g: "mcl_buckets:bucket_water"
* desc: description of the item. %s will be replaced by the level. e.g: "Water Cauldron %s/3 full"
* texture: texture of the flowing liquid e.g: "mcl_core_water_flowing.png"
## mcl_cauldrons.registered_cauldrons
Table containing chauldrons def indexed by name.

View File

@ -0,0 +1,159 @@
local has_doc = minetest.get_modpath(minetest.get_current_modname())
local function survival_give(inv, original_item, itemstack)
if inv:room_for_item("main", itemstack) then
inv:add_item("main", itemstack)
return original_item:take_item()
else
minetest.add_item(user:get_pos(), itemstack)
return original_item
end
end
local function creative_give(inv, original_item, itemstack)
if not inv:contains_item("main", itemstack) then
inv:add_item("main", itemstack)
return original_item
end
end
local function give_item(user, original_item, itemstack)
local inv = user:get_inventory()
if inv then
if minetest.is_creative_enabled(user:get_player_name()) then
creative_give(inv, original_item, itemstack)
else
survival_give(inv, original_item, itemstack)
end
end
return itemstack
end
mcl_cauldrons.registered_cauldrons = {}
function mcl_cauldrons.register_cauldron_type(def)
for water_level = 1,3 do
local id = "mcl_cauldrons:cauldron_"..def.name.."_"..water_level
mcl_cauldrons.registered_cauldrons[id] = def
minetest.register_node(id, {
description = string.format(def.desc, water_level),
_doc_items_create_entry = false,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
drawtype = "nodebox",
paramtype = "light",
is_ground_content = false,
groups = {pickaxey=1, not_in_creative_inventory=1, cauldron=(1+water_level), cauldron_filled=water_level, comparator_signal=water_level},
node_box = mcl_cauldrons.cauldron_nodeboxes[water_level],
collision_box = mcl_cauldrons.cauldron_nodeboxes[0],
selection_box = { type = "regular" },
tiles = {
"("..def.texture.."^[verticalframe:16:0"..")^mcl_cauldrons_cauldron_top.png",
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png",
"mcl_cauldrons_cauldron_side.png"
},
sounds = mcl_sounds.node_sound_metal_defaults(),
drop = "mcl_cauldrons:cauldron",
_mcl_hardness = 2,
_mcl_blast_resistance = 2,
})
-- Add entry aliases for the Help
if has_doc then
doc.add_entry_alias("nodes", "mcl_cauldrons:cauldron", "nodes", id)
end
end
end
function mcl_cauldrons.is_cauldron(name)
return minetest.get_item_group(name, "cauldron") ~= 0
end
-------------------------------------
--Functions to get/set cauldron level
-------------------------------------
function mcl_cauldrons.get_cauldron_level(pos)
local nn = minetest.get_node(pos)
return minetest.get_item_group(nn.name, "cauldron")
end
function mcl_cauldrons.set_cauldron_level(pos, type, level)
return minetest.set_node(pos, {name = mcl_cauldrons.get_cauldron_string(type, level)})
end
function mcl_cauldrons.add_cauldron_level(pos, type, number)
local current = mcl_cauldrons.get_cauldron_level(pos)
local number = current + number
if number > 4 then number = 4 end
if number < 1 then number = 1 end
mcl_cauldrons.set_cauldron_level(pos, type, number)
return number, not current == number
end
function mcl_cauldrons.get_cauldron_string(type, level)
if mcl_cauldrons.registered_cauldrons["mcl_cauldrons:cauldron_"..type.."_"..level] then
return "mcl_cauldrons:cauldron_"..type.."_"..level
elseif level == 0 then
return "mcl_cauldrons:cauldron"
else
minetest.log("warning", "[mcl_cauldrons] trying to get string from invalid cauldron params")
return "air"
end
end
----------------------------
--Functions to take cauldron
----------------------------
function mcl_cauldrons.take_cauldron(pos, itemstack, user, sounds)
local nn = minetest.get_node(pos)
if mcl_cauldrons.registered_cauldrons[nn.name] and mcl_cauldrons.registered_cauldrons[nn.name].bucket then
if user and not minetest.is_creative_enabled(user:get_player_name()) then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron"})
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
return give_item(user, original, ItemStack(mcl_cauldrons.registered_cauldrons[nn.name].bucket))
else
minetest.set_node(pos, {name="mcl_cauldrons:cauldron"})
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
return itemstack
end
else
minetest.set_node(pos, {name="mcl_cauldrons:cauldron"})
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
return itemstack
end
end
function mcl_cauldrons.take_small_cauldron(pos, itemstack, user, sounds)
local nn = minetest.get_node(pos)
if mcl_cauldrons.registered_cauldrons[nn.name] and mcl_cauldrons.registered_cauldrons[nn.name].bottle then
if user and not minetest.is_creative_enabled(user:get_player_name()) then
local number, changed = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1)
if changed then
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
local item_name = mcl_cauldrons.registered_cauldrons[nn.name].bottle
local inv = placer:get_inventory()
minetest.sound_play("mcl_potions_bottle_fill", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true)
if minetest.is_creative_enabled(placer:get_player_name()) then
-- Don't replace empty bottle in creative for convenience reasons
if not inv:contains_item("main", item_name) then
inv:add_item("main", item_name)
end
elseif itemstack:get_count() == 1 then
return item_name
else
return give_item(user, ItemStack(mcl_cauldrons.registered_cauldrons[nn.name].bucket))
end
end
else
local number = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1)
if number ~= 0 then
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
end
return itemstack
end
else
local number = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1)
if number ~= 0 then
if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end
end
return itemstack
end
end

View File

@ -1,143 +1,9 @@
local S = minetest.get_translator("mcl_cauldron")
local modpath = minetest.get_modpath(minetest.get_current_modname())
mcl_cauldrons = {}
-- Cauldron mod, adds cauldrons.
-- TODO: Extinguish fire of burning entities
-- Convenience function because the cauldron nodeboxes are very similar
local create_cauldron_nodebox = function(water_level)
local floor_y
if water_level == 0 then -- empty
floor_y = -0.1875
elseif water_level == 1 then -- 1/3 filled
floor_y = 1/16
elseif water_level == 2 then -- 2/3 filled
floor_y = 4/16
elseif water_level == 3 then -- full
floor_y = 7/16
end
return {
type = "fixed",
fixed = {
{-0.5, -0.1875, -0.5, -0.375, 0.5, 0.5}, -- Left wall
{0.375, -0.1875, -0.5, 0.5, 0.5, 0.5}, -- Right wall
{-0.375, -0.1875, 0.375, 0.375, 0.5, 0.5}, -- Back wall
{-0.375, -0.1875, -0.5, 0.375, 0.5, -0.375}, -- Front wall
{-0.5, -0.3125, -0.5, 0.5, floor_y, 0.5}, -- Floor
{-0.5, -0.5, -0.5, -0.375, -0.3125, -0.25}, -- Left front foot, part 1
{-0.375, -0.5, -0.5, -0.25, -0.3125, -0.375}, -- Left front foot, part 2
{-0.5, -0.5, 0.25, -0.375, -0.3125, 0.5}, -- Left back foot, part 1
{-0.375, -0.5, 0.375, -0.25, -0.3125, 0.5}, -- Left back foot, part 2
{0.375, -0.5, 0.25, 0.5, -0.3125, 0.5}, -- Right back foot, part 1
{0.25, -0.5, 0.375, 0.375, -0.3125, 0.5}, -- Right back foot, part 2
{0.375, -0.5, -0.5, 0.5, -0.3125, -0.25}, -- Right front foot, part 1
{0.25, -0.5, -0.5, 0.375, -0.3125, -0.375}, -- Right front foot, part 2
}
}
end
local cauldron_nodeboxes = {}
for w=0,3 do
cauldron_nodeboxes[w] = create_cauldron_nodebox(w)
end
-- Empty cauldron
minetest.register_node("mcl_cauldrons:cauldron", {
description = S("Cauldron"),
_tt_help = S("Stores water"),
_doc_items_longdesc = S("Cauldrons are used to store water and slowly fill up under rain."),
_doc_items_usagehelp = S("Place a water pucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water."),
wield_image = "mcl_cauldrons_cauldron.png",
inventory_image = "mcl_cauldrons_cauldron.png",
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
drawtype = "nodebox",
paramtype = "light",
is_ground_content = false,
groups = {pickaxey=1, deco_block=1, cauldron=1},
node_box = cauldron_nodeboxes[0],
selection_box = { type = "regular" },
tiles = {
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_top.png",
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png",
"mcl_cauldrons_cauldron_side.png"
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_hardness = 2,
_mcl_blast_resistance = 2,
})
-- Template function for cauldrons with water
local register_filled_cauldron = function(water_level, description, river_water)
local id = "mcl_cauldrons:cauldron_"..water_level
local water_tex
if river_water then
id = id .. "r"
water_tex = "default_river_water_source_animated.png^[verticalframe:16:0"
else
water_tex = "default_water_source_animated.png^[verticalframe:16:0"
end
minetest.register_node(id, {
description = description,
_doc_items_create_entry = false,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
drawtype = "nodebox",
paramtype = "light",
is_ground_content = false,
groups = {pickaxey=1, not_in_creative_inventory=1, cauldron=(1+water_level), cauldron_filled=water_level, comparator_signal=water_level},
node_box = cauldron_nodeboxes[water_level],
collision_box = cauldron_nodeboxes[0],
selection_box = { type = "regular" },
tiles = {
"("..water_tex..")^mcl_cauldrons_cauldron_top.png",
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png",
"mcl_cauldrons_cauldron_side.png"
},
sounds = mcl_sounds.node_sound_metal_defaults(),
drop = "mcl_cauldrons:cauldron",
_mcl_hardness = 2,
_mcl_blast_resistance = 2,
})
-- Add entry aliases for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_cauldrons:cauldron", "nodes", id)
end
end
-- Filled cauldrons (3 levels)
register_filled_cauldron(1, S("Cauldron (1/3 Water)"))
register_filled_cauldron(2, S("Cauldron (2/3 Water)"))
register_filled_cauldron(3, S("Cauldron (3/3 Water)"))
if minetest.get_modpath("mclx_core") then
register_filled_cauldron(1, S("Cauldron (1/3 River Water)"), true)
register_filled_cauldron(2, S("Cauldron (2/3 River Water)"), true)
register_filled_cauldron(3, S("Cauldron (3/3 River Water)"), true)
end
minetest.register_craft({
output = "mcl_cauldrons:cauldron",
recipe = {
{ "mcl_core:iron_ingot", "", "mcl_core:iron_ingot" },
{ "mcl_core:iron_ingot", "", "mcl_core:iron_ingot" },
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" },
}
})
minetest.register_abm({
label = "cauldrons",
nodenames = {"group:cauldron_filled"},
interval = 0.5,
chance = 1,
action = function(pos, node)
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.4)) do
if mcl_burning.is_burning(obj) then
mcl_burning.extinguish(obj)
local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1
minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)})
break
end
end
end
})
dofile(modpath.."/utils.lua")
dofile(modpath.."/api.lua")
dofile(modpath.."/register.lua")

View File

@ -1,3 +1,4 @@
name = mcl_cauldrons
description = Add cauldrons to mcl
depends = mcl_core, mcl_sounds
optional_depends = mclx_core, doc

View File

@ -0,0 +1,48 @@
local S = minetest.get_translator(minetest.get_current_modname())
mcl_cauldrons.register_cauldron_type({
name = "water",
bucket = "mcl_buckets:bucket_water",
bottle = "mcl_potions:water",
desc = S("Cauldron (%s/3 Water)"),
texture = "default_water_source_animated.png"
})
if minetest.get_modpath("mclx_core") then
--register_filled_cauldron(1, S("Cauldron (1/3 River Water)"), true)
--register_filled_cauldron(2, S("Cauldron (2/3 River Water)"), true)
--register_filled_cauldron(3, S("Cauldron (3/3 River Water)"), true)
end
minetest.register_craft({
output = "mcl_cauldrons:cauldron",
recipe = {
{ "mcl_core:iron_ingot", "", "mcl_core:iron_ingot" },
{ "mcl_core:iron_ingot", "", "mcl_core:iron_ingot" },
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" },
}
})
minetest.register_abm({
label = "cauldrons",
nodenames = {"group:cauldron_filled"},
interval = 0.5,
chance = 1,
action = function(pos, node)
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.4)) do
if mcl_burning.is_burning(obj) then
mcl_burning.extinguish(obj)
local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1
minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)})
break
end
end
end
})
for i = 1, 3 do --Backward compatibility
minetest.register_alias("mcl_cauldrons:cauldron_"..i, "mcl_cauldrons:cauldron_water_"..i)
end
for i = 1, 3 do
minetest.register_alias("mcl_cauldrons:cauldron_"..i.."r", "mcl_cauldrons:cauldron_river_water_"..i)
end

View File

@ -0,0 +1,63 @@
local S = minetest.get_translator(minetest.get_current_modname())
-- Convenience function because the cauldron nodeboxes are very similar
local create_cauldron_nodebox = function(water_level)
local floor_y
if water_level == 0 then -- empty
floor_y = -0.1875
elseif water_level == 1 then -- 1/3 filled
floor_y = 1/16
elseif water_level == 2 then -- 2/3 filled
floor_y = 4/16
elseif water_level == 3 then -- full
floor_y = 7/16
end
return {
type = "fixed",
fixed = {
{-0.5, -0.1875, -0.5, -0.375, 0.5, 0.5}, -- Left wall
{0.375, -0.1875, -0.5, 0.5, 0.5, 0.5}, -- Right wall
{-0.375, -0.1875, 0.375, 0.375, 0.5, 0.5}, -- Back wall
{-0.375, -0.1875, -0.5, 0.375, 0.5, -0.375}, -- Front wall
{-0.5, -0.3125, -0.5, 0.5, floor_y, 0.5}, -- Floor
{-0.5, -0.5, -0.5, -0.375, -0.3125, -0.25}, -- Left front foot, part 1
{-0.375, -0.5, -0.5, -0.25, -0.3125, -0.375}, -- Left front foot, part 2
{-0.5, -0.5, 0.25, -0.375, -0.3125, 0.5}, -- Left back foot, part 1
{-0.375, -0.5, 0.375, -0.25, -0.3125, 0.5}, -- Left back foot, part 2
{0.375, -0.5, 0.25, 0.5, -0.3125, 0.5}, -- Right back foot, part 1
{0.25, -0.5, 0.375, 0.375, -0.3125, 0.5}, -- Right back foot, part 2
{0.375, -0.5, -0.5, 0.5, -0.3125, -0.25}, -- Right front foot, part 1
{0.25, -0.5, -0.5, 0.375, -0.3125, -0.375}, -- Right front foot, part 2
}
}
end
mcl_cauldrons.cauldron_nodeboxes = {}
for w=0,3 do
mcl_cauldrons.cauldron_nodeboxes[w] = create_cauldron_nodebox(w)
end
-- Empty cauldron
minetest.register_node("mcl_cauldrons:cauldron", {
description = S("Cauldron"),
_tt_help = S("Stores water"),
_doc_items_longdesc = S("Cauldrons are used to store water and slowly fill up under rain."),
_doc_items_usagehelp = S("Place a water pucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water."),
wield_image = "mcl_cauldrons_cauldron.png",
inventory_image = "mcl_cauldrons_cauldron.png",
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
drawtype = "nodebox",
paramtype = "light",
is_ground_content = false,
groups = {pickaxey=1, deco_block=1, cauldron=1},
node_box = mcl_cauldrons.cauldron_nodeboxes[0],
selection_box = { type = "regular" },
tiles = {
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_top.png",
"mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png",
"mcl_cauldrons_cauldron_side.png"
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_hardness = 2,
_mcl_blast_resistance = 2,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 961 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -46,56 +46,6 @@ minetest.register_craft({
}
})
-- Stripped Bark
minetest.register_craft({
output = "mcl_core:stripped_oak_bark 3",
recipe = {
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_acacia_bark 3",
recipe = {
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_dark_oak_bark 3",
recipe = {
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_birch_bark 3",
recipe = {
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_spruce_bark 3",
recipe = {
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_jungle_bark 3",
recipe = {
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
}
})
minetest.register_craft({
type = 'shapeless',
output = 'mcl_core:mossycobble',

View File

@ -7,10 +7,10 @@ local WATER_ALPHA = 179
local WATER_VISC = 1
local LAVA_VISC = 7
local LIGHT_LAVA = minetest.LIGHT_MAX
local USE_TEXTURE_ALPHA = true
local USE_TEXTURE_ALPHA
if minetest.features.use_texture_alpha_string_modes then
USE_TEXTURE_ALPHA = "blend"
WATER_ALPHA = nil
end
local lava_death_messages = {
@ -40,6 +40,7 @@ minetest.register_node("mcl_core:water_flowing", {
},
sounds = mcl_sounds.node_sound_water_defaults(),
is_ground_content = false,
alpha = WATER_ALPHA,
use_texture_alpha = USE_TEXTURE_ALPHA,
paramtype = "light",
paramtype2 = "flowingliquid",
@ -85,6 +86,7 @@ S("• When water is directly below lava, the water turns into stone."),
},
sounds = mcl_sounds.node_sound_water_defaults(),
is_ground_content = false,
alpha = WATER_ALPHA,
use_texture_alpha = USE_TEXTURE_ALPHA,
paramtype = "light",
walkable = false,

View File

@ -1,4 +1,4 @@
-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood
-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves
local S = minetest.get_translator("mcl_core")
local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil
@ -48,166 +48,6 @@ local register_tree_trunk = function(subname, description_trunk, description_bar
})
end
-- Register stripped trunk
minetest.register_node("mcl_core:stripped_oak", {
description = "Stripped Oak Log",
_doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia", {
description = "Stripped Acacia Log",
_doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak", {
description = "Stripped Dark Oak Log",
_doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch", {
description = "Stripped Birch Log",
_doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce", {
description = "Stripped Spruce Log",
_doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle", {
description = "Stripped Jungle Log",
_doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
-- Register stripped bark
minetest.register_node("mcl_core:stripped_oak_bark", {
description = "Stripped Oak Bark",
_doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia_bark", {
description = "Stripped Acacia Bark",
_doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak_bark", {
description = "Stripped Dark Oak Bark",
_doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch_bark", {
description = "Stripped Birch Bark",
_doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce_bark", {
description = "Stripped Spruce Bark",
_doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle_bark", {
description = "Stripped Jungle Bark",
_doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
local register_wooden_planks = function(subname, description, tiles)
minetest.register_node("mcl_core:"..subname, {
description = description,
@ -386,4 +226,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from
-- Node aliases
minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree")
minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves")
minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

View File

@ -169,16 +169,7 @@ minetest.register_node("mcl_end:dragon_egg", {
sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 9,
_mcl_hardness = 3,
on_punch = function(pos, node)
local max_dist = vector.new(15, 7, 15)
local positions = minetest.find_nodes_in_area(vector.subtract(pos, max_dist), vector.add(pos, max_dist), "air", false)
if #positions > 0 then
local tpos = positions[math.random(#positions)]
minetest.remove_node(pos)
minetest.set_node(tpos, node)
minetest.check_for_falling(tpos)
end
end,
-- TODO: Make dragon egg teleport on punching
})

View File

@ -58,9 +58,8 @@ local function spawn_crystal(pos)
for _, crystal in pairs(crystals) do
crystal_explode(crystal)
end
local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3))
mcl_structures.call_struct(portal_pos, "end_exit_portal")
minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = portal_pos
local dragon = minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon")
dragon:get_luaentity()._egg_spawn_pos = minetest.pos_to_string(vector.add(portal_center, {x = 0, y = 4, z = 0}))
end
minetest.register_entity("mcl_end:crystal", {
@ -71,7 +70,7 @@ minetest.register_entity("mcl_end:crystal", {
collisionbox = {-1, 0.5, -1, 1, 2.5, 1},
mesh = "mcl_end_crystal.b3d",
textures = {"mcl_end_crystal.png"},
collide_with_objects = false,
collide_with_objects = true,
},
on_punch = crystal_explode,
on_activate = set_crystal_animation,
@ -79,54 +78,6 @@ minetest.register_entity("mcl_end:crystal", {
_hittable_by_projectile = true
})
minetest.register_entity("mcl_end:crystal_beam", {
initial_properties = {
physical = false,
visual = "cube",
visual_size = {x = 1, y = 1, z = 1},
textures = {
"mcl_end_crystal_beam.png^[transformR90",
"mcl_end_crystal_beam.png^[transformR90",
"mcl_end_crystal_beam.png",
"mcl_end_crystal_beam.png",
"blank.png",
"blank.png",
},
static_save = false,
},
spin = 0,
init = function(self, dragon, crystal)
self.dragon, self.crystal = dragon, crystal
crystal:get_luaentity().beam = self.object
dragon:get_luaentity().beam = self.object
end,
on_deactivate = function(self)
if self.crystal and self.crystal:get_luaentity() then
self.crystal:get_luaentity().beam = nil
end
if self.dragon and self.dragon:get_luaentity() then
self.dragon:get_luaentity().beam = nil
end
end,
on_step = function(self, dtime)
if self.dragon and self.dragon:get_luaentity() and self.crystal and self.crystal:get_luaentity() then
self.spin = self.spin + dtime * math.pi * 2 / 4
local dragon_pos, crystal_pos = self.dragon:get_pos(), self.crystal:get_pos()
dragon_pos.y = dragon_pos.y + 4
crystal_pos.y = crystal_pos.y + 2
self.object:set_pos(vector.divide(vector.add(dragon_pos, crystal_pos), 2))
local rot = vector.dir_to_rotation(vector.direction(dragon_pos, crystal_pos))
rot.z = self.spin
self.object:set_rotation(rot)
self.object:set_properties({visual_size = {x = 0.5, y = 0.5, z = vector.distance(dragon_pos, crystal_pos)}})
else
self.object:remove()
end
end,
})
minetest.register_craftitem("mcl_end:crystal", {
inventory_image = "mcl_end_crystal_item.png",
description = S("End Crystal"),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

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