Compare commits
52 Commits
master
...
chat-comma
Author | SHA1 | Date |
---|---|---|
|
e463d16298 | |
|
0a35714019 | |
|
0a802a2cc1 | |
|
5ade58f919 | |
|
25495d2dcd | |
|
e0fcfc1888 | |
|
698b107cb3 | |
|
b9c0dc80f3 | |
|
43d398b0b2 | |
|
163aa720c2 | |
|
e7d3939e28 | |
|
6f0777d36d | |
|
9b0f2c4cbf | |
|
c307b5304f | |
|
16529330dd | |
|
8eebdd3461 | |
|
073707f53c | |
|
d7ac1b7cb5 | |
|
d00a5c74d2 | |
|
f9a03a3c98 | |
|
0c96ff672d | |
|
46677a38ae | |
|
f8804c5e56 | |
|
3137c86f67 | |
|
2a28bf215d | |
|
86f01eed75 | |
|
a51bbb6974 | |
|
11384bd73c | |
|
669a9ff0a4 | |
|
783146f32e | |
|
31e256e1e2 | |
|
5f00d47ec2 | |
|
0d3147b13d | |
|
a22188ccf4 | |
|
f90243f6e5 | |
|
884097a8e5 | |
|
72ddaf33f6 | |
|
19e83fc2fb | |
|
43c641f84f | |
|
155548f384 | |
|
f7b832508f | |
|
9e7ec24c0e | |
|
5b5b525d32 | |
|
e334665365 | |
|
88a971fe6f | |
|
5425a01097 | |
|
1f5076cfd0 | |
|
7139ca1395 | |
|
84de4ea728 | |
|
59ab7e6ae6 | |
|
d5874b4062 | |
|
d72fa76757 |
|
@ -0,0 +1,74 @@
|
|||
# API documentation of mcl_commands
|
||||
|
||||
The mcl_commands API allows you to register and overide complex commands.
|
||||
This mod is derivated from ChatCommandBuilder by rubenwardy
|
||||
|
||||
Some public functions are not documented here but they are for internal use only.
|
||||
|
||||
## Technical differences from ChatCommandBuilder
|
||||
|
||||
* subcommand aditional specific privs
|
||||
* new types: `json`, `color`, `nodename` an maybe more in the future
|
||||
|
||||
|
||||
## Public Functions
|
||||
|
||||
### `mcl_commands.register_command("exemple", def)`
|
||||
|
||||
This is a function which is called when an item is dispensed by the dispenser.
|
||||
These are the parameters:
|
||||
|
||||
```
|
||||
mcl_commands.register_command("exemple", {
|
||||
func = function(cmd) --function executed on registration
|
||||
cmd:sub(":name:username title :params:json", { --create a new subcommand called "title" with defined patterns
|
||||
func = function(name, target, json)
|
||||
return a_cool_function(target, json) --function executed if the params match the patterns
|
||||
end,
|
||||
privs = {settime = true}, --subcommand aditional specific privs
|
||||
})
|
||||
end,
|
||||
description = "Controls text displayed on the screen.", --the description of the command
|
||||
params = "<target> command <params>", --very basic explaination of the syntax of the command (will be semi-automatic in the future)
|
||||
privs = {server = true}, --global privs
|
||||
})
|
||||
```
|
||||
|
||||
Register a complex chatcommand. If a chat command with the same name is already registered, the program will fail.
|
||||
|
||||
### `mcl_commands.overide_command("exemple", def)`
|
||||
|
||||
Same as above but will overide existing command.
|
||||
|
||||
### `mcl_commands.register_chatcommand_alias(alias, cmd, [bypass])`
|
||||
|
||||
Register an alias called `alias` of the `cmd` command.
|
||||
If the setting `mcl_builtin_commands_overide` is set to `false`, the function will silently fail.
|
||||
If `bypass` is set to `true` the function will not take care of the above setting.
|
||||
Will warn if trying to alias to already existing command.
|
||||
|
||||
### `mcl_commands.rename_chatcommand(newname, cmd, [bypass])`
|
||||
|
||||
Rename `cmd` command to `newname`.
|
||||
If the setting `mcl_builtin_commands_overide` is set to `false`, the function will silently fail.
|
||||
If `bypass` is set to `true` the function will not take care of the above setting.
|
||||
Will warn if trying to rename to already existing command.
|
||||
|
||||
### paterns
|
||||
|
||||
mcl_commands adds many types for patterns
|
||||
If not specified, a value will be by default with the word pattern.
|
||||
|
||||
* pos value must be pos
|
||||
* text value must be text WARNING: this pattern must be the last pattern of the subcommand!!
|
||||
* number value must be number
|
||||
* int value must be integer
|
||||
* word value must be word
|
||||
* alpha value must be alphanumeric
|
||||
* modname value must be a valid modname
|
||||
* alphascore
|
||||
* alphanumeric
|
||||
* username: value must be a valid username
|
||||
* json: value must be a json string (will be parsed automaticaly)
|
||||
* color value must be a color string or a valid named color
|
||||
* nodename value must be a valid (existing) node or item name
|
|
@ -0,0 +1,374 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
local C = minetest.colorize
|
||||
|
||||
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
|
||||
|
||||
local parse_json = minetest.parse_json
|
||||
local get_modpath = minetest.get_modpath
|
||||
|
||||
mcl_commands.types = {
|
||||
pos = {"%(? *(%-?[%d.]+) *,? *(%-?[%d.]+) *,? *(%-?[%d.]+) *%)?",
|
||||
function(res, pointer)
|
||||
local pos = {
|
||||
x = tonumber(res[pointer]),
|
||||
y = tonumber(res[pointer + 1]),
|
||||
z = tonumber(res[pointer + 2])
|
||||
}
|
||||
if pos.x and pos.y and pos.z then
|
||||
return nil, pos, pointer+3
|
||||
else
|
||||
return S("Pos is invalid!")
|
||||
end
|
||||
end},
|
||||
text = {"(.+)",
|
||||
function(res, pointer)
|
||||
if res[pointer] == tostring(res[pointer]) then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Text is invalid!")
|
||||
end
|
||||
end},
|
||||
number = {"(%-?[%d.]+)}",
|
||||
function(res, pointer)
|
||||
if res[pointer] == tonumber(res[pointer]) then
|
||||
return nil, tonumber(res[pointer]), pointer+1
|
||||
else
|
||||
return S("Number is invalid!")
|
||||
end
|
||||
end},
|
||||
int = {"(%-?[%d]+)}",
|
||||
function(res, pointer)
|
||||
if res[pointer] == math.floor(tonumber(res[pointer])) then
|
||||
return nil, tonumber(res[pointer]), pointer+1
|
||||
else
|
||||
return S("Int is invalid!")
|
||||
end
|
||||
end},
|
||||
word = {"([^ ]+)",
|
||||
function(res, pointer)
|
||||
if res[pointer] == tostring(res[pointer]) then
|
||||
return nil, tostring(res[pointer]), pointer+1
|
||||
else
|
||||
return S("Word is invalid!")
|
||||
end
|
||||
end},
|
||||
quotestring = {'["]+(.+)["]+',
|
||||
function(res, pointer)
|
||||
if res[pointer] == tostring(res[pointer]) then
|
||||
return nil, string.sub(tostring(res[pointer]), 2, #res[pointer]-1), pointer+1
|
||||
else
|
||||
return S("String is invalid!")
|
||||
end
|
||||
end},
|
||||
alpha = {"([A-Za-z]+)}",
|
||||
function(res, pointer)
|
||||
if res[pointer] then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Alpha is invalid!")
|
||||
end
|
||||
end},
|
||||
modname = {"([a-z0-9_]+)}",
|
||||
function(res, pointer)
|
||||
if get_modpath(res[pointer]) then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Modname is invalid!")
|
||||
end
|
||||
end},
|
||||
alphascore = {"([A-Za-z_]+)",
|
||||
function(res, pointer)
|
||||
if res[pointer] then --What is alphascore?
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Alphascore is invalid!")
|
||||
end
|
||||
end},
|
||||
alphanumeric = {"([A-Za-z0-9]+)}",
|
||||
function(res, pointer)
|
||||
if res[pointer] then --What is alphanumerical?
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Alphanumerical is invalid!")
|
||||
end
|
||||
end},
|
||||
username = {"([A-Za-z0-9-_]+)",
|
||||
function(res, pointer)
|
||||
--if minetest.player_exists(res[pointer]) then
|
||||
if res[pointer] then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Player doesn't exist.")
|
||||
end
|
||||
end},
|
||||
target = {"([A-Za-z0-9-_]+)",
|
||||
function(res, pointer)
|
||||
--if minetest.player_exists(res[pointer]) then
|
||||
if res[pointer] then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Player doesn't exist.")
|
||||
end
|
||||
end},
|
||||
json = {"(.+)", --FIXME
|
||||
function(res, pointer)
|
||||
local parsed = parse_json(res[pointer])
|
||||
if parsed then
|
||||
return nil, parsed, pointer+1
|
||||
else
|
||||
return S("Json failed to parse!")
|
||||
end
|
||||
end},
|
||||
color = {"([^ ]+)", --FIXME
|
||||
function(res, pointer)
|
||||
local color = mcl_util.get_color(res[pointer])
|
||||
if color then
|
||||
return nil, color, pointer+1
|
||||
else
|
||||
return S("Color is not a valid color name or hexadecimal!")
|
||||
end
|
||||
end},
|
||||
nodename = {"(%l+[%w_]+%:?[_%l]+[%w_]*)",
|
||||
function(res, pointer)
|
||||
if minetest.registered_items[res[pointer]] then
|
||||
return nil, res[pointer], pointer+1
|
||||
else
|
||||
return S("Nodename is invalid")
|
||||
end
|
||||
end},
|
||||
}
|
||||
|
||||
function mcl_commands.register_command(name, def)
|
||||
def = def or {}
|
||||
local cmd = mcl_commands.build(name, def)
|
||||
if minetest.registered_chatcommands[name] then
|
||||
error("[mcl_commands] Failed to register command: ["..name.."] command already existing! Use mcl_commands.overide_command() if you want to overide existing command")
|
||||
end
|
||||
minetest.register_chatcommand(name, cmd)
|
||||
minetest.log("action", "[mcl_commands] ["..name.."] command registered successfully")
|
||||
return cmd
|
||||
end
|
||||
|
||||
function mcl_commands.override_command(name, def)
|
||||
def = def or {}
|
||||
local cmd = mcl_commands.build(name, def)
|
||||
if minetest.registered_chatcommands[name] then
|
||||
minetest.unregister_chatcommand(name)
|
||||
end
|
||||
minetest.register_chatcommand(name, cmd)
|
||||
minetest.log("action", "[mcl_commands] ["..name.."] command overridden successfully")
|
||||
return cmd
|
||||
end
|
||||
|
||||
local STATE_READY = 1
|
||||
local STATE_PARAM = 2
|
||||
local STATE_PARAM_TYPE = 3
|
||||
local bad_chars = {"(", ")", ".", "%", "+", "-", "*", "?", "[", "^", "$"}
|
||||
local function escape(char)
|
||||
if bad_chars[char] then
|
||||
return "%" .. char
|
||||
else
|
||||
return char
|
||||
end
|
||||
end
|
||||
|
||||
local dprint = function() end
|
||||
|
||||
function mcl_commands.build(name, chat_def)
|
||||
local cmd = {
|
||||
_subs = {}
|
||||
}
|
||||
function cmd:sub(route, def)
|
||||
dprint("Parsing " .. route)
|
||||
|
||||
if string.trim then
|
||||
route = string.trim(route)
|
||||
end
|
||||
|
||||
local sub = {
|
||||
pattern = "^",
|
||||
params = {},
|
||||
func = def.func,
|
||||
privs = def.privs or {},
|
||||
desc = def.desc,
|
||||
params_desc = def.params or "",
|
||||
}
|
||||
|
||||
-- End of param reached: add it to the pattern
|
||||
local param = ""
|
||||
local param_type = ""
|
||||
local should_be_eos = false
|
||||
local function finishParam()
|
||||
if param ~= "" and param_type ~= "" then
|
||||
dprint(" - Found param " .. param .. " type " .. param_type)
|
||||
|
||||
local pattern = mcl_commands.types[param_type][1]
|
||||
if not pattern then
|
||||
error("Unrecognised param_type=" .. param_type)
|
||||
end
|
||||
|
||||
sub.pattern = sub.pattern .. pattern
|
||||
|
||||
table.insert(sub.params, param_type)
|
||||
|
||||
param = ""
|
||||
param_type = ""
|
||||
end
|
||||
end
|
||||
|
||||
-- Iterate through the route to find params
|
||||
local state = STATE_READY
|
||||
local catching_space = false
|
||||
local match_space = " " -- change to "%s" to also catch tabs and newlines
|
||||
local catch_space = match_space.."+"
|
||||
for i = 1, #route do
|
||||
local c = route:sub(i, i)
|
||||
if should_be_eos then
|
||||
error("Should be end of string. Nothing is allowed after a param of type text.")
|
||||
end
|
||||
|
||||
if state == STATE_READY then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param")
|
||||
state = STATE_PARAM
|
||||
param_type = "word"
|
||||
catching_space = false
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found space")
|
||||
if not catching_space then
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
end
|
||||
else
|
||||
catching_space = false
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
end
|
||||
elseif state == STATE_PARAM then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param type")
|
||||
state = STATE_PARAM_TYPE
|
||||
param_type = ""
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found whitespace, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param = param .. c
|
||||
end
|
||||
elseif state == STATE_PARAM_TYPE then
|
||||
if c:match(match_space) then
|
||||
print(" - Found space, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param_type = param_type .. c
|
||||
end
|
||||
end
|
||||
end
|
||||
dprint(" - End of route")
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. "$"
|
||||
dprint("Pattern: " .. sub.pattern)
|
||||
|
||||
table.insert(self._subs, sub)
|
||||
end
|
||||
|
||||
if chat_def.func then
|
||||
chat_def.func(cmd)
|
||||
end
|
||||
|
||||
cmd.func = function(name, param)
|
||||
local msg
|
||||
for i = 1, #cmd._subs do
|
||||
local sub = cmd._subs[i]
|
||||
local res = { string.match(param, sub.pattern) }
|
||||
if #res > 0 then
|
||||
local pointer = 1
|
||||
local params = { name }
|
||||
for j = 1, #sub.params do
|
||||
local param = sub.params[j]
|
||||
local value
|
||||
if mcl_commands.types[param] then
|
||||
msg, value, pointer = mcl_commands.check_type(param, res, pointer)
|
||||
table.insert(params, value)
|
||||
else
|
||||
table.insert(params, res[pointer])
|
||||
pointer = pointer + 1
|
||||
end
|
||||
end
|
||||
local can_execute, missing_privs = minetest.check_player_privs(name, sub.privs)
|
||||
if can_execute then
|
||||
if table.unpack then
|
||||
-- lua 5.2 or later
|
||||
return sub.func(table.unpack(params))
|
||||
else
|
||||
-- lua 5.1 or earlier
|
||||
return sub.func(unpack(params))
|
||||
end
|
||||
else
|
||||
local missing_privs_str = ""
|
||||
for i = 1, #missing_privs do
|
||||
if not i == #missing_privs then
|
||||
missing_privs_str = missing_privs_str..missing_privs[i].." "
|
||||
else
|
||||
missing_privs_str = missing_privs_str..missing_privs[i]
|
||||
end
|
||||
end
|
||||
return false, C(mcl_colors.RED, S("You don't have permission to run this command (missing privilege: "..missing_privs_str..")"))
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, C(mcl_colors.RED, msg)
|
||||
end
|
||||
if chat_def.params then
|
||||
cmd.params = chat_def.params
|
||||
else
|
||||
cmd.params = ""
|
||||
end
|
||||
cmd.privs = chat_def.privs
|
||||
cmd.description = chat_def.description
|
||||
return cmd
|
||||
end
|
||||
|
||||
function mcl_commands.check_type(type, res, pointer)
|
||||
return mcl_commands.types[type][2](res, pointer)
|
||||
end
|
||||
|
||||
function mcl_commands.register_chatcommand_alias(alias, cmd, bypass)
|
||||
if not bypass then bypass = false end
|
||||
if minetest.registered_chatcommands[alias] then
|
||||
minetest.log("warning", "[mcl_commands] trying to alias ["..cmd.."] to already existing ["..alias.."] command")
|
||||
elseif minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass then
|
||||
minetest.register_chatcommand(alias, minetest.chatcommands[cmd])
|
||||
minetest.log("action", "[mcl_commands] ["..cmd.."] command aliased successfully to ["..alias.."]")
|
||||
else
|
||||
minetest.log("action", "[mcl_commands] ["..cmd.."] command not aliased to ["..alias.."]")
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_commands.rename_chatcommand(newname, cmd, bypass)
|
||||
if not bypass then bypass = false end
|
||||
if minetest.registered_chatcommands[newname] then
|
||||
minetest.log("warning", "[mcl_commands] trying to rename ["..cmd.."] to already existing ["..alias.."] command")
|
||||
elseif minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass then
|
||||
minetest.register_chatcommand(newname, minetest.chatcommands[cmd])
|
||||
minetest.unregister_chatcommand(cmd)
|
||||
minetest.log("action", "[mcl_commands] ["..cmd.."] command renamed successfully to ["..newname.."]")
|
||||
else
|
||||
minetest.log("action", "[mcl_commands] ["..cmd.."] command not renamed to ["..newname.."]")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
--mcl_commands
|
||||
--derivated from ChatCommandBuilder by @rubenwardy
|
||||
|
||||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
mcl_commands = {}
|
||||
|
||||
dofile(modpath.."/api.lua")
|
||||
dofile(modpath.."/utils.lua")
|
|
@ -0,0 +1,6 @@
|
|||
name = mcl_commands
|
||||
author = AFCMS
|
||||
description = MCL2 commands API
|
||||
depends = mcl_colors, mcl_util
|
||||
optional_depends =
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
function mcl_commands.get_target_selector(target, pos, name)
|
||||
if minetest.player_exists(target) then
|
||||
return nil, minetest.get_player_by_name(target)
|
||||
elseif target == "@a" then
|
||||
return nil, minetest.get_connected_players()
|
||||
elseif target == "@r" then
|
||||
local connected = minetest.get_connected_players()
|
||||
return nil, connected[math.random(1, #connected)]
|
||||
elseif target == "@s" then
|
||||
if name then
|
||||
local player = minetest.get_player_by_name(name)
|
||||
end
|
||||
if player then
|
||||
return nil, player
|
||||
else
|
||||
return S("Not a valid player")
|
||||
end
|
||||
elseif target == "@p" then
|
||||
local smallest = math.huge
|
||||
local nearest
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
local distance = vector.distance(pos, player:get_pos())
|
||||
if distance < min_distance then
|
||||
min_distance = distance
|
||||
nearest = player
|
||||
end
|
||||
end
|
||||
if nearest then
|
||||
return nil, nearest
|
||||
else
|
||||
return S("No player online")
|
||||
end
|
||||
elseif target == "@e" then
|
||||
return minetest.luaentities --TODO: add filtering of not valid entities.
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
mcl_util.registered_blacklisted_entities = {}
|
||||
function mcl_util.register_blacklisted_entities(type)
|
||||
mcl_util.registered_blacklisted_entities[type] = true
|
||||
end
|
||||
function mcl_util.get_real_entities()
|
||||
for key, val in pairs(minetest.luaentities) do
|
||||
local def = minetest.registered_entities[minetest.luaentities[key].name]
|
||||
if not mcl_util.registered_blacklisted_entities[def.type] then
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,5 @@
|
|||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
mcl_util = {}
|
||||
|
||||
-- Based on minetest.rotate_and_place
|
||||
|
@ -418,3 +420,5 @@ function mcl_util.get_color(colorstr)
|
|||
return colorstr, hex
|
||||
end
|
||||
end
|
||||
|
||||
dofile(modpath.."/entities.lua")
|
|
@ -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
|
||||
|
@ -859,12 +866,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
|
||||
|
@ -3413,6 +3418,7 @@ local mob_activate = function(self, staticdata, def, dtime)
|
|||
self.timer = 0
|
||||
self.blinktimer = 0
|
||||
self.blinkstatus = false
|
||||
self.collide_with_objects = false
|
||||
|
||||
-- check existing nametag
|
||||
if not self.nametag then
|
||||
|
@ -3556,7 +3562,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
|
||||
|
||||
|
@ -3901,12 +3907,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 +3925,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)
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--###################
|
||||
--################### AGENT - seemingly unused
|
||||
--################### AGENT
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
@ -128,18 +128,7 @@ mobs:register_mob("mobs_mc:blaze", {
|
|||
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", {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
@ -140,9 +138,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"},
|
||||
|
@ -253,158 +248,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)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
mcl_mobs
|
|
@ -61,22 +61,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
|||
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
|
||||
|
|
|
@ -346,28 +346,29 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
--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
|
||||
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
|
||||
if self.provoked == "staring" then
|
||||
self.provoked = "broke_contact"
|
||||
end
|
||||
end
|
||||
|
||||
goto continue
|
||||
end
|
||||
|
||||
--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
|
||||
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
|
||||
if self.provoked == "staring" then
|
||||
self.provoked = "broke_contact"
|
||||
end
|
||||
end
|
||||
|
||||
::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -561,189 +562,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)
|
||||
|
|
|
@ -75,20 +75,7 @@ mobs:register_mob("mobs_mc:ghast", {
|
|||
})
|
||||
|
||||
|
||||
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", {
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -510,56 +510,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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -157,137 +157,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 +272,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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -36,12 +36,12 @@ end
|
|||
|
||||
local last_id = 0
|
||||
|
||||
function mcl_bossbars.add_bar(player, def, dynamic, priority)
|
||||
function mcl_bossbars.add_bar(player, def)
|
||||
local name = player:get_player_name()
|
||||
local bars = mcl_bossbars.bars[name]
|
||||
local bar = {text = def.text, priority = priority or 0}
|
||||
local bar = {text = def.text}
|
||||
bar.color, bar.image = get_color_info(def.color, def.percentage)
|
||||
if dynamic then
|
||||
if def.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
|
||||
|
@ -55,7 +55,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority)
|
|||
end
|
||||
end
|
||||
table.insert(bars, bar)
|
||||
if not dynamic then
|
||||
if not def.dynamic then
|
||||
bar.raw_color = def.color
|
||||
bar.id = last_id + 1
|
||||
last_id = bar.id
|
||||
|
@ -69,11 +69,10 @@ function mcl_bossbars.remove_bar(id)
|
|||
mcl_bossbars.static[id] = nil
|
||||
end
|
||||
|
||||
function mcl_bossbars.update_bar(id, def, priority)
|
||||
function mcl_bossbars.update_bar(id, def)
|
||||
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)
|
||||
|
@ -82,15 +81,14 @@ function mcl_bossbars.update_boss(luaentity, name, color)
|
|||
text = luaentity.nametag,
|
||||
percentage = math.floor(luaentity.health / luaentity.hp_max * 100),
|
||||
color = color,
|
||||
dynamic = true,
|
||||
}
|
||||
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)
|
||||
for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do
|
||||
if obj:is_player() then
|
||||
mcl_bossbars.add_bar(obj, bardef)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -117,7 +115,6 @@ minetest.register_globalstep(function()
|
|||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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")
|
||||
|
|
Before Width: | Height: | Size: 361 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 531 B |
Before Width: | Height: | Size: 439 B |
Before Width: | Height: | Size: 382 B |
Before Width: | Height: | Size: 438 B |
Before Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 523 B |
Before Width: | Height: | Size: 447 B |
Before Width: | Height: | Size: 556 B |
|
@ -79,54 +79,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"),
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB |
|
@ -1,9 +1,6 @@
|
|||
-- TODO: whenever it becomes possible to fully implement kelp without the
|
||||
-- plantlike_rooted limitation, please update accordingly.
|
||||
--
|
||||
-- TODO: whenever it becomes possible to make kelp grow infinitely without
|
||||
-- resorting to making intermediate kelp stem node, please update accordingly.
|
||||
--
|
||||
-- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle.
|
||||
-- However, because of the plantlike_rooted hack, we'll just allow it for now.
|
||||
|
||||
|
@ -194,18 +191,17 @@ end
|
|||
|
||||
|
||||
-- Converts param2 to kelp height.
|
||||
-- For the special case where the max param2 is reached, interpret that as the
|
||||
-- 16th kelp stem.
|
||||
function kelp.get_height(param2)
|
||||
return math_floor(param2 / 16) + math_floor(param2 % 16 / 8)
|
||||
return math_floor(param2 / 16)
|
||||
end
|
||||
|
||||
|
||||
-- Obtain pos and node of the tip of kelp.
|
||||
function kelp.get_tip(pos, height)
|
||||
-- Optional params: height
|
||||
local height = height or kelp.get_height(mt_get_node(pos).param2)
|
||||
local pos_tip = {x=pos.x, y=pos.y+height+1, z=pos.z}
|
||||
function kelp.get_tip(pos, param2)
|
||||
-- Optional params: param2
|
||||
local height = kelp.get_height(param2 or mt_get_node(pos).param2)
|
||||
local pos_tip = {x=pos.x, y=pos.y, z=pos.z}
|
||||
pos_tip.y = pos_tip.y + height + 1
|
||||
return pos_tip, mt_get_node(pos_tip), height
|
||||
end
|
||||
|
||||
|
@ -214,7 +210,7 @@ end
|
|||
function kelp.find_unsubmerged(pos, node, height)
|
||||
-- Optional params: node, height
|
||||
local node = node or mt_get_node(pos)
|
||||
local height = height or ((node.param2 >= 0 and node.param2 < 16) and 1) or kelp.get_height(node.param2)
|
||||
local height = height or kelp.get_height(node.param2)
|
||||
|
||||
local walk_pos = {x=pos.x, z=pos.z}
|
||||
local y = pos.y
|
||||
|
@ -231,8 +227,7 @@ end
|
|||
|
||||
-- Obtain next param2.
|
||||
function kelp.next_param2(param2)
|
||||
-- param2 max value is 255, so adding to 256 causes overflow.
|
||||
return math_min(param2+16 - param2 % 16, 255);
|
||||
return param2+16 - param2 % 16
|
||||
end
|
||||
|
||||
|
||||
|
@ -316,7 +311,7 @@ function kelp.init_timer(pos, pos_hash)
|
|||
end
|
||||
|
||||
|
||||
-- Apply next kelp height. The surface is swapped. so on_construct is skipped.
|
||||
-- Apply next kelp height.
|
||||
function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing)
|
||||
-- Modified params: node
|
||||
-- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing
|
||||
|
@ -372,9 +367,9 @@ end
|
|||
|
||||
|
||||
-- Drops the items for detached kelps.
|
||||
function kelp.detach_drop(pos, height)
|
||||
-- Optional params: height
|
||||
local height = height or kelp.get_height(mt_get_node(pos).param2)
|
||||
function kelp.detach_drop(pos, param2)
|
||||
-- Optional params: param2
|
||||
local height = kelp.get_height(param2 or mt_get_node(pos).param2)
|
||||
local y = pos.y
|
||||
local walk_pos = {x=pos.x, z=pos.z}
|
||||
for i=1,height do
|
||||
|
@ -389,18 +384,17 @@ end
|
|||
-- Synonymous to digging the kelp.
|
||||
-- NOTE: this is intended for whenever kelp truly becomes segmented plants
|
||||
-- instead of rooted to the floor. Don't try to remove dig_pos.
|
||||
function kelp.detach_dig(dig_pos, pos, drop, node, height)
|
||||
-- Optional params: drop, node, height
|
||||
function kelp.detach_dig(dig_pos, pos, node, drop)
|
||||
-- Optional params: drop
|
||||
|
||||
local node = node or mt_get_node(pos)
|
||||
local height = height or kelp.get_height(node.param2)
|
||||
local param2 = node.param2
|
||||
-- pos.y points to the surface, offset needed to point to the first kelp.
|
||||
local new_height = dig_pos.y - (pos.y+1)
|
||||
|
||||
-- Digs the entire kelp.
|
||||
if new_height <= 0 then
|
||||
if drop then
|
||||
kelp.detach_drop(dig_pos, height)
|
||||
kelp.detach_drop(dig_pos, param2)
|
||||
end
|
||||
mt_set_node(pos, {
|
||||
name=mt_registered_nodes[node.name].node_dig_prediction,
|
||||
|
@ -410,7 +404,7 @@ function kelp.detach_dig(dig_pos, pos, drop, node, height)
|
|||
-- Digs the kelp beginning at a height.
|
||||
else
|
||||
if drop then
|
||||
kelp.detach_drop(dig_pos, height - new_height)
|
||||
kelp.detach_drop(dig_pos, param2 - new_height)
|
||||
end
|
||||
mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height})
|
||||
end
|
||||
|
@ -422,7 +416,7 @@ end
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
function kelp.surface_on_dig(pos, node, digger)
|
||||
kelp.detach_dig(pos, pos, true, node)
|
||||
kelp.detach_dig(pos, pos, node, true)
|
||||
end
|
||||
|
||||
|
||||
|
@ -436,11 +430,11 @@ function kelp.surface_on_timer(pos)
|
|||
local pos_hash
|
||||
|
||||
-- Update detahed kelps
|
||||
local dig_pos,_, height = kelp.find_unsubmerged(pos, node)
|
||||
local dig_pos = kelp.find_unsubmerged(pos, node)
|
||||
if dig_pos then
|
||||
pos_hash = mt_hash_node_position(pos)
|
||||
mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true)
|
||||
kelp.detach_dig(dig_pos, pos, true, node, height)
|
||||
kelp.detach_dig(dig_pos, pos, node, true)
|
||||
kelp.store_age(kelp.roll_init_age(), pos, pos_hash)
|
||||
end
|
||||
|
||||
|
@ -469,7 +463,7 @@ function kelp.surface_on_destruct(pos)
|
|||
|
||||
-- on_falling callback. Activated by pistons for falling nodes too.
|
||||
if kelp.is_falling(pos, node) then
|
||||
kelp.detach_drop(pos, kelp.get_height(node.param2))
|
||||
kelp.detach_drop(pos, node.param2)
|
||||
end
|
||||
|
||||
-- Removes position from queue
|
||||
|
@ -480,7 +474,7 @@ end
|
|||
|
||||
function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta)
|
||||
-- Pistons moving falling nodes will have already activated on_falling callback.
|
||||
kelp.detach_dig(pos, pos, mt_get_item_group(node.name, "falling_node") ~= 1, node)
|
||||
kelp.detach_dig(pos, pos, node, mt_get_item_group(node.name, "falling_node") ~= 1)
|
||||
end
|
||||
|
||||
|
||||
|
@ -524,7 +518,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
|||
end
|
||||
|
||||
|
||||
local pos_tip, node_tip, def_tip, new_surface, height
|
||||
local pos_tip, node_tip, def_tip, new_kelp
|
||||
-- Kelp must also be placed on the top/tip side of the surface/kelp
|
||||
if pos_under.y >= pos_above.y then
|
||||
return itemstack
|
||||
|
@ -532,33 +526,31 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
|||
|
||||
-- When placed on kelp.
|
||||
if mt_get_item_group(nu_name, "kelp") == 1 then
|
||||
height = kelp.get_height(node_under.param2)
|
||||
pos_tip,node_tip = kelp.get_tip(pos_under, height)
|
||||
pos_tip,node_tip = kelp.get_tip(pos_under, node_under.param2)
|
||||
def_tip = mt_registered_nodes[node_tip.name]
|
||||
|
||||
-- When placed on surface.
|
||||
else
|
||||
new_surface = false
|
||||
new_kelp = false
|
||||
for _,surface in pairs(kelp.surfaces) do
|
||||
if nu_name == surface.nodename then
|
||||
node_under.name = "mcl_ocean:kelp_" ..surface.name
|
||||
node_under.param2 = 0
|
||||
new_surface = true
|
||||
new_kelp = true
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Surface must support kelp
|
||||
if not new_surface then
|
||||
if not new_kelp then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
pos_tip = pos_above
|
||||
node_tip = mt_get_node(pos_above)
|
||||
def_tip = mt_registered_nodes[node_tip.name]
|
||||
height = 0
|
||||
end
|
||||
|
||||
-- Next kelp must also be submerged in water.
|
||||
-- New kelp must also be submerged in water.
|
||||
local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip)
|
||||
local submerged = kelp.is_submerged(node_tip)
|
||||
if not submerged then
|
||||
|
@ -570,19 +562,14 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
|||
if def_node.sounds then
|
||||
mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true)
|
||||
end
|
||||
-- TODO: get rid of rooted plantlike hack
|
||||
if height < 16 then
|
||||
kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing)
|
||||
else
|
||||
mt_add_item(pos_tip, "mcl_ocean:kelp")
|
||||
end
|
||||
kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing)
|
||||
if not mt_is_creative_enabled(player_name) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
|
||||
-- Initialize age and timer when it's planted on a new surface.
|
||||
-- Initialize age and timer when it's a new kelp
|
||||
local pos_hash = mt_hash_node_position(pos_under)
|
||||
if new_surface then
|
||||
if new_kelp then
|
||||
kelp.init_age(pos_under, nil, pos_hash)
|
||||
kelp.init_timer(pos_under, pos_hash)
|
||||
else
|
||||
|
|
|
@ -490,12 +490,10 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
|
|||
end
|
||||
|
||||
if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then
|
||||
local pos1, pos2, p = param.next_chunk_1, param.next_chunk_2, param.next_pos
|
||||
if p.x >= pos1.x and p.x <= pos2.x and p.y >= pos1.y and p.y <= pos2.y and p.z >= pos1.z and p.z <= pos2.z then
|
||||
log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(p))
|
||||
minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = p, pos1 = pos1, pos2 = pos2, name=name, obj=obj})
|
||||
return
|
||||
end
|
||||
local pos1, pos2, pos = param.next_chunk_1, param.next_chunk_2, param.next_pos
|
||||
log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(pos))
|
||||
minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = pos, pos1 = pos1, pos2 = pos2, name=name, obj=obj})
|
||||
return
|
||||
end
|
||||
|
||||
log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal")
|
||||
|
@ -538,7 +536,7 @@ local function create_portal(pos, limit1, limit2, name, obj)
|
|||
-- Basically the copy of code above, with minor additions to continue the search in single additional chunk below:
|
||||
local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z}
|
||||
local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1)
|
||||
local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z}
|
||||
local next_pos = {x = pos.x, y=next_chunk_2.y, z = pos.z}
|
||||
if limit1 and limit1.x and limit1.y and limit1.z then
|
||||
pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)}
|
||||
next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)}
|
||||
|
|
|
@ -352,56 +352,6 @@ minetest.register_tool("mcl_tools:shovel_diamond", {
|
|||
})
|
||||
|
||||
-- Axes
|
||||
|
||||
local make_stripped_trunk = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing)
|
||||
local node = minetest.get_node(pos)
|
||||
local node_name = node.name
|
||||
if placer and not placer:get_player_control().sneak then
|
||||
if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].on_rightclick then
|
||||
return minetest.registered_nodes[node_name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
|
||||
end
|
||||
end
|
||||
if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
|
||||
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
||||
return itemstack
|
||||
end
|
||||
if not minetest.is_creative_enabled(placer:get_player_name()) then
|
||||
-- Add wear (as if digging a axey node)
|
||||
local toolname = itemstack:get_name()
|
||||
local wear = mcl_autogroup.get_wear(toolname, "axey")
|
||||
itemstack:add_wear(wear)
|
||||
end
|
||||
if node_name == "mcl_core:tree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak"})
|
||||
elseif node_name == "mcl_core:darktree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak"})
|
||||
elseif node_name == "mcl_core:acaciatree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia"})
|
||||
elseif node_name == "mcl_core:birchtree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch"})
|
||||
elseif node_name == "mcl_core:sprucetree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce"})
|
||||
elseif node_name == "mcl_core:jungletree" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle"})
|
||||
elseif node_name == "mcl_core:tree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak_bark"})
|
||||
elseif node_name == "mcl_core:darktree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak_bark"})
|
||||
elseif node_name == "mcl_core:acaciatree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia_bark"})
|
||||
elseif node_name == "mcl_core:birchtree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch_bark"})
|
||||
elseif node_name == "mcl_core:sprucetree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce_bark"})
|
||||
elseif node_name == "mcl_core:jungletree_bark" then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle_bark"})
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.register_tool("mcl_tools:axe_wood", {
|
||||
description = S("Wooden Axe"),
|
||||
_doc_items_longdesc = axe_longdesc,
|
||||
|
@ -415,7 +365,6 @@ minetest.register_tool("mcl_tools:axe_wood", {
|
|||
damage_groups = {fleshy=7},
|
||||
punch_attack_uses = 30,
|
||||
},
|
||||
on_place = make_stripped_trunk,
|
||||
sound = { breaks = "default_tool_breaks" },
|
||||
_repair_material = "group:wood",
|
||||
_mcl_toollike_wield = true,
|
||||
|
@ -435,7 +384,6 @@ minetest.register_tool("mcl_tools:axe_stone", {
|
|||
damage_groups = {fleshy=9},
|
||||
punch_attack_uses = 66,
|
||||
},
|
||||
on_place = make_stripped_trunk,
|
||||
sound = { breaks = "default_tool_breaks" },
|
||||
_repair_material = "mcl_core:cobble",
|
||||
_mcl_toollike_wield = true,
|
||||
|
@ -456,7 +404,6 @@ minetest.register_tool("mcl_tools:axe_iron", {
|
|||
damage_groups = {fleshy=9},
|
||||
punch_attack_uses = 126,
|
||||
},
|
||||
on_place = make_stripped_trunk,
|
||||
sound = { breaks = "default_tool_breaks" },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
_mcl_toollike_wield = true,
|
||||
|
@ -476,7 +423,6 @@ minetest.register_tool("mcl_tools:axe_gold", {
|
|||
damage_groups = {fleshy=7},
|
||||
punch_attack_uses = 17,
|
||||
},
|
||||
on_place = make_stripped_trunk,
|
||||
sound = { breaks = "default_tool_breaks" },
|
||||
_repair_material = "mcl_core:gold_ingot",
|
||||
_mcl_toollike_wield = true,
|
||||
|
@ -496,7 +442,6 @@ minetest.register_tool("mcl_tools:axe_diamond", {
|
|||
damage_groups = {fleshy=9},
|
||||
punch_attack_uses = 781,
|
||||
},
|
||||
on_place = make_stripped_trunk,
|
||||
sound = { breaks = "default_tool_breaks" },
|
||||
_repair_material = "mcl_core:diamond",
|
||||
_mcl_toollike_wield = true,
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.register_chatcommand_alias("?", "help", false)
|
||||
mcl_commands.register_chatcommand_alias("pardon", "unban", false)
|
||||
mcl_commands.rename_chatcommand("stop", "shutdown", false)
|
||||
mcl_commands.register_chatcommand_alias("tell", "msg", false)
|
||||
mcl_commands.register_chatcommand_alias("w", "msg", false)
|
||||
mcl_commands.register_chatcommand_alias("tp", "teleport", false)
|
||||
mcl_commands.rename_chatcommand("clear", "clearinv", false)
|
||||
|
||||
mcl_commands.register_command("banlist", {
|
||||
func = function(cmd)
|
||||
cmd:sub("", {
|
||||
func = function(name)
|
||||
return true, S("Ban list: @1", minetest.get_ban_list())
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("List bans"),
|
||||
params = "",
|
||||
privs = minetest.chatcommands["ban"].privs,
|
||||
})
|
|
@ -0,0 +1,38 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.bossbar = {}
|
||||
mcl_commands.bossbar.dynamic_bosbars = {}
|
||||
|
||||
--1.13 feature
|
||||
--TODO: toggle it with setting/mod
|
||||
mcl_commands.register_command("bossbar", {
|
||||
func = function(cmd)
|
||||
cmd:sub("add :id: :string:word", {
|
||||
func = function(name, id, string)
|
||||
mcl_commands.bossbar.dynamic_bosbars[id] = {text=string, color="white", percentage=100}
|
||||
return true, "Super"
|
||||
end,
|
||||
})
|
||||
cmd:sub("set :id: players :value:word", {
|
||||
func = function(name, id, value)
|
||||
mcl_commands.bossbar.dynamic_bosbars[id].players = value
|
||||
local def = mcl_commands.bossbar.dynamic_bosbars[id]
|
||||
mcl_bossbars.update_bar(minetest.get_player_by_name(name), def.text, def.color, def.percentage)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
cmd:sub("remove", {
|
||||
func = function(name, target)
|
||||
return
|
||||
end,
|
||||
})
|
||||
cmd:sub("get", {
|
||||
func = function(name, target)
|
||||
return
|
||||
end,
|
||||
})
|
||||
end,
|
||||
description = "Can add, configure or remove a custom bossbar.",
|
||||
params = S("[<target>]"),
|
||||
privs = {server = true},
|
||||
})
|
|
@ -0,0 +1,9 @@
|
|||
--Basic commands for mcl2
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
for _,filename in pairs({"kill", "setblock", "seed", "summon", "say", "list", "sound", "title", "bossbar"}) do
|
||||
dofile(modpath.."/"..filename..".lua")
|
||||
end
|
||||
|
||||
dofile(modpath.."/alias.lua")
|
|
@ -41,19 +41,20 @@ local function handle_kill_command(suspect, victim)
|
|||
return true
|
||||
end
|
||||
|
||||
if minetest.registered_chatcommands["kill"] then
|
||||
minetest.unregister_chatcommand("kill")
|
||||
end
|
||||
minetest.register_chatcommand("kill", {
|
||||
params = S("[<name>]"),
|
||||
description = S("Kill player or yourself"),
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
if(param == "") then
|
||||
-- Selfkill
|
||||
return handle_kill_command(name, name)
|
||||
else
|
||||
return handle_kill_command(name, param)
|
||||
end
|
||||
mcl_commands.override_command("kill", {
|
||||
func = function(cmd)
|
||||
cmd:sub("", {
|
||||
func = function(name)
|
||||
return handle_kill_command(name, name)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":target:username", {
|
||||
func = function(name, target)
|
||||
return handle_kill_command(name, target)
|
||||
end,
|
||||
})
|
||||
end,
|
||||
description = "Kill player or yourself.",
|
||||
params = S("[<target>]"),
|
||||
privs = {server = true},
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.register_command("list", {
|
||||
func = function(cmd)
|
||||
cmd:sub("", {
|
||||
func = function(name)
|
||||
local player_list = minetest.get_connected_players()
|
||||
local header = S("There are @1/@2 players online:", #player_list, minetest.settings:get("max_users") or "unknown").."\n"
|
||||
local players = {}
|
||||
for _, player in ipairs(player_list) do
|
||||
table.insert(players, player:get_player_name())
|
||||
end
|
||||
return true, header..table.concat(players, ", ")
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("Show who is logged on"),
|
||||
params = "",
|
||||
privs = {},
|
||||
})
|
|
@ -0,0 +1,24 @@
|
|||
# textdomain: mcl_commands
|
||||
Players can't be killed right now, damage has been disabled.=Spieler können jetzt nicht getötet werden, der Schaden wurde deaktiviert.
|
||||
Player @1 does not exist.=Spieler @1 existiert nicht.
|
||||
You are already dead=Sie sind schon tot
|
||||
@1 is already dead=@1 ist schon tot
|
||||
@1 committed suicide.=@1 beging Selbstmord.
|
||||
@1 was killed by @2.=@1 wurde von @2 getötet.
|
||||
[<name>]=[<Name>]
|
||||
Kill player or yourself=Spieler oder sich selbst töten
|
||||
Can use /say=Kann „/say“ benutzen
|
||||
<message>=<Nachricht>
|
||||
Send a message to every player=Nachricht an alle Spieler senden
|
||||
Invalid usage, see /help say.=Falsche Benutzung, siehe „/help say“.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <Node-Bezeichner>
|
||||
Set node at given position=Node (Block) an der gegebenen Position platzieren
|
||||
Invalid node=Unültiger Node
|
||||
@1 spawned.=@1 gespawnt.
|
||||
Invalid parameters (see /help setblock)=Ungültige Parameter (siehe „/help setblock”)
|
||||
List bans=Bannliste anzeigen
|
||||
Ban list: @1=Bannliste: @1
|
||||
There are @1/@2 players online:=
|
||||
Show who is logged on=Anzeigen, wer eingeloggt ist
|
||||
Displays the world seed=Den Seed der Welt anzeigen
|
||||
Only peaceful mobs allowed!=Nur friedliche Mobs erlaubt!
|
|
@ -0,0 +1,24 @@
|
|||
# textdomain: mcl_commands
|
||||
Players can't be killed right now, damage has been disabled.=Los jugadores no pueden ser asesinados en este momento, el daño ha sido desactivado.
|
||||
Player @1 does not exist.=El jugador @1 no existe.
|
||||
You are already dead=Ya estas muerto
|
||||
@1 is already dead=@1 ya esta muerto
|
||||
@1 committed suicide.=@1 se suicidó.
|
||||
@1 was killed by @2.=@1 fue asesinado por @2.
|
||||
[<name>]=[<Nombre>]
|
||||
Kill player or yourself=Mata al jugador o a ti mismo
|
||||
Can use /say=Puedes usar /say
|
||||
<message>=<Mensaje>
|
||||
Send a message to every player=Envía un mensaje a todos los jugadores
|
||||
Invalid usage, see /help=Uso no válido, (Revisa el comando "/help say")
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <ID nodo>
|
||||
Set node at given position=Establecer nodo en la posición dada
|
||||
Invalid node=Nodo no válido
|
||||
@1 spawned.=@1 generado.
|
||||
Invalid parameters (see /help setblock)=Parámetros no válidos (Revisa el comando "/help setblock")
|
||||
List bans=Lista de prohibiciones
|
||||
Ban list: @1=Lista de baneados: @1
|
||||
There are @1/@2 players online:=
|
||||
Show who is logged on=Mostrar quién ha iniciado sesión
|
||||
Displays the world seed=Muestra la semilla del mundo
|
||||
Only peaceful mobs allowed!=¡Solo se permiten animales pacíficos!
|
|
@ -0,0 +1,24 @@
|
|||
# textdomain: mcl_commands
|
||||
Players can't be killed right now, damage has been disabled.=Les joueurs ne peuvent pas être tués pour le moment, les dégâts ont été désactivés.
|
||||
Player @1 does not exist.=Le joueur @1 n'existe pas.
|
||||
You are already dead=Tu es déjà mort
|
||||
@1 is already dead=@1 est déjà mort
|
||||
@1 committed suicide.=@1 s'est suicidé.
|
||||
@1 was killed by @2.=@1 a été tué par @2.
|
||||
[<name>]=[<nom>]
|
||||
Kill player or yourself=Tuez un joueur ou vous-même
|
||||
Can use /say=Peut utiliser /say
|
||||
<message>=<message>
|
||||
Send a message to every player=Envoyez un message à chaque joueur
|
||||
Invalid usage, see /help say.=Utilisation non valide, voir /help say.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <NodeString>
|
||||
Set node at given position=Placer le noeud à une position donnée
|
||||
Invalid node=Noeud non valide
|
||||
@1 spawned.=@1 est apparu.
|
||||
Invalid parameters (see /help setblock)=Paramètres invalides (voir /help setblock)
|
||||
List bans=Liste des interdictions
|
||||
Ban list: @1=Liste d'interdiction: @1
|
||||
There are @1/@2 players online:=Il y a @1/@2 joueurs en ligne:
|
||||
Show who is logged on=Afficher qui est connecté
|
||||
Displays the world seed=Affiche la graine du monde
|
||||
Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisées!
|
|
@ -0,0 +1,24 @@
|
|||
# textdomain: mcl_commands
|
||||
Players can't be killed right now, damage has been disabled.=Игроки не могут быть убиты прямо сейчас, урон отключён.
|
||||
Player @1 does not exist.=Игрок @1 не существует.
|
||||
You are already dead=Вы уже мертвы
|
||||
@1 is already dead=@1 уже мертв(а)
|
||||
@1 committed suicide.=@1 совершил(а) роскомнадзор.
|
||||
@1 was killed by @2.=@1 был(а) убит(а) @2.
|
||||
[<name>]=[<имя>]
|
||||
Kill player or yourself=Убить игрока или себя
|
||||
Can use /say=Можно использовать /say
|
||||
<message>=<сообщение>
|
||||
Send a message to every player=Отправляет сообщение всем игрокам
|
||||
Invalid usage, see /help say.=Недопустимое использование, см. /help say.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <СтрокаУзла>
|
||||
Set node at given position=Устанавливает узел в заданной позиции
|
||||
Invalid node=Неправильный узел
|
||||
@1 spawned.=@1 возродился(ась).
|
||||
Invalid parameters (see /help setblock)=Недопустимые параметры (см. /help setblock)
|
||||
List bans=Список банов
|
||||
Ban list: @1=Бан-лист: @1
|
||||
There are @1/@2 players online:=
|
||||
Show who is logged on=Показывает, кто подключён
|
||||
Displays the world seed=Показывает значение зерна мира (seed)
|
||||
Only peaceful mobs allowed!=Включены только мирные мобы!
|
|
@ -0,0 +1,24 @@
|
|||
# textdomain: mcl_commands
|
||||
Players can't be killed right now, damage has been disabled.=
|
||||
Player @1 does not exist.=
|
||||
You are already dead=
|
||||
@1 is already dead=
|
||||
@1 committed suicide.=
|
||||
@1 was killed by @2.=
|
||||
[<name>]=
|
||||
Kill player or yourself=
|
||||
Can use /say=
|
||||
<message>=
|
||||
Send a message to every player=
|
||||
Invalid usage, see /help say.=
|
||||
<X>,<Y>,<Z> <NodeString>=
|
||||
Set node at given position=
|
||||
Invalid node=
|
||||
@1 spawned.=
|
||||
Invalid parameters (see /help setblock)=
|
||||
List bans=
|
||||
Ban list: @1=
|
||||
There are @1/@2 players online:=
|
||||
Show who is logged on=
|
||||
Displays the world seed=
|
||||
Only peaceful mobs allowed!=
|
|
@ -0,0 +1,3 @@
|
|||
name=mcl_basic_commands
|
||||
depends=mcl_commands
|
||||
optional_depends=mcl_death_message
|
|
@ -0,0 +1,19 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_privilege("announce", {
|
||||
description = S("Can use /say"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
|
||||
mcl_commands.register_command("say", {
|
||||
func = function(cmd)
|
||||
cmd:sub(":message:text", {
|
||||
func = function(name, message)
|
||||
minetest.chat_send_all(("["..name.."] "..message))
|
||||
return true
|
||||
end})
|
||||
end,
|
||||
description = S("Send a message to every player"),
|
||||
params = S("<message>"),
|
||||
privs = {announce = true},
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.register_command("seed", {
|
||||
func = function(cmd)
|
||||
cmd:sub("", {
|
||||
func = function(name)
|
||||
return true, "Seed: "..minetest.get_mapgen_setting("seed")
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("Displays the world seed"),
|
||||
params = "",
|
||||
privs = {},
|
||||
})
|
|
@ -0,0 +1,35 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.register_command("setblock", {
|
||||
func = function(cmd)
|
||||
cmd:sub(":pos:pos :node:nodename", {
|
||||
func = function(name, pos, node)
|
||||
minetest.set_node(pos, {name=node})
|
||||
return true, S("@1 spawned.", node)
|
||||
--return false, S("Invalid parameters (see /help setblock)")
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("Set node at given position"),
|
||||
params = S("<X>,<Y>,<Z> <NodeString>"),
|
||||
privs = {give=true, interact=true},
|
||||
})
|
||||
|
||||
|
||||
--DEBUG: must be removed later
|
||||
mcl_commands.register_command("setdebug", {
|
||||
func = function(cmd)
|
||||
cmd:sub(":node:nodename", {
|
||||
func = function(name, node)
|
||||
minetest.set_node({x=0,y=0,z=0}, {name=node})
|
||||
return true, S("@1 spawned.", node)
|
||||
--return false, S("Invalid parameters (see /help setblock)")
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("Set node at given position"),
|
||||
params = S("<X>,<Y>,<Z> <NodeString>"),
|
||||
privs = {give=true, interact=true},
|
||||
})
|
|
@ -0,0 +1,19 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
mcl_commands.register_command("playsound", {
|
||||
func = function(cmd)
|
||||
cmd:sub(":sound:word :target:username", { --TODO:replace by upcomming types
|
||||
func = function(name, sound, target)
|
||||
if minetest.player_exists(target) then
|
||||
minetest.sound_play({name = sound}, {to_player = target}, true) --TODO:add source, gain, pitch
|
||||
else
|
||||
return false, S("Target is invalid!!") --TODO: add mc chat message
|
||||
end
|
||||
end,
|
||||
privs = {},
|
||||
})
|
||||
end,
|
||||
description = S("Play a sound. Arguments: <sound>: name of the sound. <target>: Target."),
|
||||
params = S("<sound> <target>"),
|
||||
privs = {server = true},
|
||||
})
|
|
@ -0,0 +1,142 @@
|
|||
local C = minetest.colorize
|
||||
local has_mcl_colors = minetest.get_modpath("mcl_colors")
|
||||
|
||||
local huds_idx = {}
|
||||
huds_idx.title = {}
|
||||
huds_idx.subtitle = {}
|
||||
huds_idx.actionbar = {}
|
||||
|
||||
mcl_title = {}
|
||||
mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20}
|
||||
mcl_title.layout = {}
|
||||
mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 5}
|
||||
mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.3}, size = 2}
|
||||
mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = -10}, size = 1}
|
||||
|
||||
local function gametick_to_secondes(gametick)
|
||||
return gametick / 20
|
||||
end
|
||||
|
||||
function mcl_title.set(playername, type, data)
|
||||
if not data.color then
|
||||
data.color = "white"
|
||||
end
|
||||
local _, hex_color = mcl_util.get_color(data.color)
|
||||
if not hex_color then
|
||||
return false, "Invalid color: " .. data.color
|
||||
end
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player and data then
|
||||
if huds_idx[type][playername] then
|
||||
player:hud_remove(huds_idx[type][playername])
|
||||
end
|
||||
local stay = player:get_meta():get_int("mcl_title:stay") or 3
|
||||
huds_idx[type][playername] = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = mcl_title.layout[type].position,
|
||||
alignment = mcl_title.layout[type].alignment,
|
||||
text = data.text,
|
||||
size = {x = mcl_title.layout[type].size},
|
||||
number = hex_color,
|
||||
z_index = 1100
|
||||
})
|
||||
minetest.after(stay, function()
|
||||
if huds_idx[type][playername] then
|
||||
player:hud_remove(huds_idx[type][playername])
|
||||
end
|
||||
huds_idx[type][playername] = nil
|
||||
end)
|
||||
return true, "Title command executed successfuly"
|
||||
else
|
||||
return false, "Player doesn't exist or json failed to parse"
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_title.remove(playername, type)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player then
|
||||
if huds_idx[type][playername] then
|
||||
player:hud_remove(huds_idx[type][playername])
|
||||
end
|
||||
end
|
||||
huds_idx[type][playername] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function mcl_title.times(playername, stay)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player then
|
||||
local meta = player:get_meta()
|
||||
--meta:set_int("mcl_title:fadeIn", gametick_to_secondes(fadein))
|
||||
meta:set_int("mcl_title:stay", gametick_to_secondes(stay))
|
||||
--meta:set_int("mcl_title:fadeOut", gametick_to_secondes(fadeout))
|
||||
return true
|
||||
else
|
||||
return false, "Player doesn't exist"
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_newplayer(function(player)
|
||||
local meta = player:get_meta()
|
||||
--meta:set_int("mcl_title:fadeIn", gametick_to_secondes(mcl_title.defaults.fadein))
|
||||
meta:set_int("mcl_title:stay", gametick_to_secondes(mcl_title.defaults.stay))
|
||||
--meta:set_int("mcl_title:fadeOut", gametick_to_secondes(mcl_title.defaults.fadeout))
|
||||
end)
|
||||
|
||||
function mcl_title.clear(playername)
|
||||
mcl_title.remove(playername, "title")
|
||||
mcl_title.remove(playername, "subtitle")
|
||||
mcl_title.remove(playername, "actionbar")
|
||||
return true
|
||||
end
|
||||
|
||||
function mcl_title.reset(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player then
|
||||
local meta = player:get_meta()
|
||||
--meta:set_int("mcl_title:fadeIn", gametick_to_secondes(mcl_title.defaults.fadein))
|
||||
meta:set_int("mcl_title:stay", gametick_to_secondes(mcl_title.defaults.stay))
|
||||
--meta:set_int("mcl_title:fadeOut", gametick_to_secondes(mcl_title.defaults.fadeout))
|
||||
return true
|
||||
else
|
||||
return false, "Player not found!"
|
||||
end
|
||||
end
|
||||
|
||||
mcl_commands.register_command("title", {
|
||||
func = function(cmd)
|
||||
cmd:sub(":name:username title :params:json", {
|
||||
func = function(name, target, json)
|
||||
return mcl_title.set(target, "title", json)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":name:username subtitle :params:json", {
|
||||
func = function(name, target, json)
|
||||
return mcl_title.set(target, "subtitle", json)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":name:username actionbar :params:json", {
|
||||
func = function(name, target, json)
|
||||
return mcl_title.set(target, "actionbar", json)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":name:username times :stay:int", {
|
||||
func = function(name, target, stay)
|
||||
return mcl_title.times(target, stay)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":name:username clear", {
|
||||
func = function(name, target)
|
||||
return mcl_title.clear(target)
|
||||
end,
|
||||
})
|
||||
cmd:sub(":name:username reset", {
|
||||
func = function(name, target)
|
||||
return mcl_title.reset(target)
|
||||
end,
|
||||
})
|
||||
end,
|
||||
description = "Controls text displayed on the screen.",
|
||||
params = "<target> command <params>",
|
||||
privs = {server = true},
|
||||
})
|
|
@ -1,30 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
local function register_chatcommand_alias(alias, cmd)
|
||||
local def = minetest.chatcommands[cmd]
|
||||
minetest.register_chatcommand(alias, def)
|
||||
end
|
||||
|
||||
local function rename_chatcommand(newname, cmd)
|
||||
local def = minetest.chatcommands[cmd]
|
||||
minetest.register_chatcommand(newname, def)
|
||||
minetest.unregister_chatcommand(cmd)
|
||||
end
|
||||
|
||||
if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then
|
||||
register_chatcommand_alias("?", "help")
|
||||
register_chatcommand_alias("pardon", "unban")
|
||||
rename_chatcommand("stop", "shutdown")
|
||||
register_chatcommand_alias("tell", "msg")
|
||||
register_chatcommand_alias("w", "msg")
|
||||
register_chatcommand_alias("tp", "teleport")
|
||||
rename_chatcommand("clear", "clearinv")
|
||||
|
||||
minetest.register_chatcommand("banlist", {
|
||||
description = S("List bans"),
|
||||
privs = minetest.chatcommands["ban"].privs,
|
||||
func = function(name)
|
||||
return true, S("Ban list: @1", minetest.get_ban_list())
|
||||
end,
|
||||
})
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
dofile(modpath.."/kill.lua")
|
||||
dofile(modpath.."/setblock.lua")
|
||||
dofile(modpath.."/seed.lua")
|
||||
dofile(modpath.."/summon.lua")
|
||||
dofile(modpath.."/say.lua")
|
||||
dofile(modpath.."/list.lua")
|
||||
dofile(modpath.."/sound.lua")
|
||||
|
||||
dofile(modpath.."/alias.lua")
|
|
@ -1,14 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_chatcommand("list", {
|
||||
description = S("Show who is logged on"),
|
||||
params = "",
|
||||
privs = {},
|
||||
func = function(name)
|
||||
local players = ""
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
players = players..player:get_player_name().."\n"
|
||||
end
|
||||
minetest.chat_send_player(name, players)
|
||||
end
|
||||
})
|
|
@ -1,4 +0,0 @@
|
|||
name = mcl_commands
|
||||
author = Wuzzy
|
||||
description = MCL2 commands
|
||||
optional_depends = mcl_death_messages
|
|
@ -1,18 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_privilege("announce", {
|
||||
description = S("Can use /say"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
minetest.register_chatcommand("say", {
|
||||
params = S("<message>"),
|
||||
description = S("Send a message to every player"),
|
||||
privs = {announce=true},
|
||||
func = function(name, param)
|
||||
if not param then
|
||||
return false, S("Invalid usage, see /help say.")
|
||||
end
|
||||
minetest.chat_send_all(("["..name.."] "..param))
|
||||
return true
|
||||
end,
|
||||
})
|
|
@ -1,10 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_chatcommand("seed", {
|
||||
description = S("Displays the world seed"),
|
||||
params = "",
|
||||
privs = {},
|
||||
func = function(name)
|
||||
minetest.chat_send_player(name, "Seed: "..minetest.get_mapgen_setting("seed"))
|
||||
end
|
||||
})
|
|
@ -1,22 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_chatcommand("setblock", {
|
||||
params = S("<X>,<Y>,<Z> <NodeString>"),
|
||||
description = S("Set node at given position"),
|
||||
privs = {give=true, interact=true},
|
||||
func = function(name, param)
|
||||
local p = {}
|
||||
local nodestring = nil
|
||||
p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$")
|
||||
p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z)
|
||||
if p.x and p.y and p.z and nodestring then
|
||||
local itemstack = ItemStack(nodestring)
|
||||
if itemstack:is_empty() or not minetest.registered_nodes[itemstack:get_name()] then
|
||||
return false, S("Invalid node")
|
||||
end
|
||||
minetest.set_node(p, {name=nodestring})
|
||||
return true, S("@1 spawned.", nodestring)
|
||||
end
|
||||
return false, S("Invalid parameters (see /help setblock)")
|
||||
end,
|
||||
})
|
|
@ -1,48 +0,0 @@
|
|||
local S = minetest.get_translator("mcl_commands")
|
||||
|
||||
minetest.register_chatcommand("playsound",{
|
||||
params = S("<sound> <target>"), --TODO:add source
|
||||
description = S("Play a sound. Arguments: <sound>: name of the sound. <target>: Target."),
|
||||
privs = {server = true},
|
||||
func = function(name, params)
|
||||
local P = {}
|
||||
local i = 0
|
||||
for str in string.gmatch(params, "([^ ]+)") do
|
||||
i = i + 1
|
||||
P[i] = str
|
||||
end
|
||||
|
||||
local params = {}
|
||||
if P[1] == tostring(P[1]) then
|
||||
params.name = P[1]
|
||||
else
|
||||
return false, S("Sound name is invalid!") --TODO: add mc chat message
|
||||
end
|
||||
|
||||
if P[2] == tostring(P[2]) and minetest.player_exists(P[2]) then
|
||||
params.target = P[2]
|
||||
else
|
||||
return false, S("Target is invalid!!")
|
||||
end
|
||||
|
||||
-- if P[3] then
|
||||
-- params.pos = nil --TODO:position
|
||||
-- else
|
||||
-- params.pos = nil
|
||||
-- end
|
||||
|
||||
-- if P[4] == tonumber(P[4]) then
|
||||
-- params.gain = P[4]
|
||||
-- else
|
||||
-- params.gain = 1.0
|
||||
-- end
|
||||
|
||||
-- if P[5] == tonumber(P[5]) then
|
||||
-- params.pitch = P[5]
|
||||
-- else
|
||||
-- params.pitch = 1.0
|
||||
-- end
|
||||
minetest.sound_play({name = params.name}, {to_player = params.target}, true) --TODO: /stopsound
|
||||
return true
|
||||
end,
|
||||
})
|
|
@ -22,48 +22,11 @@ local mcl_playerplus_internal = {}
|
|||
local def = {}
|
||||
local time = 0
|
||||
|
||||
local player_collision = function(player)
|
||||
|
||||
local pos = player:get_pos()
|
||||
local vel = player:get_velocity()
|
||||
local x = 0
|
||||
local z = 0
|
||||
local width = .75
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||
|
||||
if object and (object:is_player()
|
||||
or (object:get_luaentity()._cmi_is_mob == true and object ~= player)) then
|
||||
|
||||
local pos2 = object:get_pos()
|
||||
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
|
||||
local force = (width + 0.5) - vector.distance(
|
||||
{x = pos.x, y = 0, z = pos.z},
|
||||
{x = pos2.x, y = 0, z = pos2.z})
|
||||
|
||||
x = x + (vec.x * force)
|
||||
z = z + (vec.z * force)
|
||||
end
|
||||
end
|
||||
|
||||
return({x,z})
|
||||
end
|
||||
|
||||
-- converts yaw to degrees
|
||||
local function degrees(rad)
|
||||
return rad * 180.0 / math.pi
|
||||
end
|
||||
|
||||
local pi = math.pi
|
||||
local atann = math.atan
|
||||
local atan = function(x)
|
||||
if not x or x ~= x then
|
||||
return 0
|
||||
else
|
||||
return atann(x)
|
||||
end
|
||||
end
|
||||
|
||||
local dir_to_pitch = function(dir)
|
||||
local dir2 = vector.normalize(dir)
|
||||
local xz = math.abs(dir.x) + math.abs(dir.z)
|
||||
|
@ -119,50 +82,12 @@ end
|
|||
|
||||
local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos
|
||||
|
||||
|
||||
minetest.register_on_punchplayer(function(player, hitter, damage)
|
||||
if hitter:is_player() then
|
||||
if hitter:get_player_control().aux1 then
|
||||
player:add_velocity(hitter:get_velocity())
|
||||
end
|
||||
if hitter:get_velocity().y < -6 then
|
||||
player:set_hp(player:get_hp() - (damage * math.random(0.50 , 0.75)))
|
||||
local pos = player:get_pos()
|
||||
minetest.add_particlespawner({
|
||||
amount = 15,
|
||||
time = 0.1,
|
||||
minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5},
|
||||
maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5},
|
||||
minvel = {x=-0.1, y=-0.1, z=-0.1},
|
||||
maxvel = {x=0.1, y=0.1, z=0.1},
|
||||
minacc = {x=0, y=0, z=0},
|
||||
maxacc = {x=0, y=0, z=0},
|
||||
minexptime = 1,
|
||||
maxexptime = 2,
|
||||
minsize = 1.5,
|
||||
maxsize = 1.5,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "mcl_particles_crit.png^[colorize:#bc7a57:127",
|
||||
})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
|
||||
time = time + dtime
|
||||
|
||||
for _,player in pairs(get_connected_players()) do
|
||||
|
||||
c_x, c_y = unpack(player_collision(player))
|
||||
|
||||
if player:get_velocity().x + player:get_velocity().y < .5 and c_x + c_y > 0 then
|
||||
--minetest.chat_send_player(player:get_player_name(), "pushed at " .. c_x + c_y .. " parsecs.")
|
||||
player:add_velocity({x=c_x, y=0, z=c_y})
|
||||
end
|
||||
|
||||
--[[
|
||||
_ _ _
|
||||
__ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___
|
||||
|
@ -210,26 +135,26 @@ minetest.register_globalstep(function(dtime)
|
|||
|
||||
if parent then
|
||||
local parent_yaw = degrees(parent:get_yaw())
|
||||
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0))
|
||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||
elseif controls.sneak then
|
||||
-- controls head pitch when sneaking
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
|
||||
-- sets eye height, and nametag color accordingly
|
||||
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
|
||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
|
||||
-- sneaking body conrols
|
||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||
elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then
|
||||
-- set head pitch and yaw when swimming
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0))
|
||||
-- sets eye height, and nametag color accordingly
|
||||
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
-- control body bone when swimming
|
||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0))
|
||||
else
|
||||
-- sets eye height, and nametag color accordingly
|
||||
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0))
|
||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0))
|
||||
|
|