Compare commits
52 Commits
master
...
chat-comma
Author | SHA1 | Date |
---|---|---|
AFCMS | e463d16298 | |
AFCMS | 0a35714019 | |
AFCMS | 0a802a2cc1 | |
AFCMS | 5ade58f919 | |
AFCMS | 25495d2dcd | |
AFCMS | e0fcfc1888 | |
AFCMS | 698b107cb3 | |
AFCMS | b9c0dc80f3 | |
AFCMS | 43d398b0b2 | |
AFCMS | 163aa720c2 | |
AFCMS | e7d3939e28 | |
AFCMS | 6f0777d36d | |
AFCMS | 9b0f2c4cbf | |
AFCMS | c307b5304f | |
AFCMS | 16529330dd | |
AFCMS | 8eebdd3461 | |
AFCMS | 073707f53c | |
AFCMS | d7ac1b7cb5 | |
AFCMS | d00a5c74d2 | |
AFCMS | f9a03a3c98 | |
AFCMS | 0c96ff672d | |
AFCMS | 46677a38ae | |
AFCMS | f8804c5e56 | |
AFCMS | 3137c86f67 | |
AFCMS | 2a28bf215d | |
AFCMS | 86f01eed75 | |
AFCMS | a51bbb6974 | |
AFCMS | 11384bd73c | |
AFCMS | 669a9ff0a4 | |
AFCMS | 783146f32e | |
AFCMS | 31e256e1e2 | |
AFCMS | 5f00d47ec2 | |
AFCMS | 0d3147b13d | |
AFCMS | a22188ccf4 | |
AFCMS | f90243f6e5 | |
AFCMS | 884097a8e5 | |
AFCMS | 72ddaf33f6 | |
AFCMS | 19e83fc2fb | |
AFCMS | 43c641f84f | |
AFCMS | 155548f384 | |
AFCMS | f7b832508f | |
AFCMS | 9e7ec24c0e | |
AFCMS | 5b5b525d32 | |
AFCMS | e334665365 | |
AFCMS | 88a971fe6f | |
AFCMS | 5425a01097 | |
AFCMS | 1f5076cfd0 | |
AFCMS | 7139ca1395 | |
AFCMS | 84de4ea728 | |
AFCMS | 59ab7e6ae6 | |
AFCMS | d5874b4062 | |
AFCMS | 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 = {}
|
mcl_util = {}
|
||||||
|
|
||||||
-- Based on minetest.rotate_and_place
|
-- Based on minetest.rotate_and_place
|
||||||
|
@ -418,3 +420,5 @@ function mcl_util.get_color(colorstr)
|
||||||
return colorstr, hex
|
return colorstr, hex
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
dofile(modpath.."/entities.lua")
|
|
@ -61,6 +61,8 @@ end
|
||||||
|
|
||||||
-- Load settings
|
-- Load settings
|
||||||
local damage_enabled = minetest.settings:get_bool("enable_damage")
|
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 disable_blood = minetest.settings:get_bool("mobs_disable_blood")
|
||||||
local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false
|
local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= 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)
|
||||||
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
|
-- pathfinding settings
|
||||||
local enable_pathfinding = true
|
local enable_pathfinding = true
|
||||||
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
|
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, "^[colorize:#FF000040")
|
||||||
remove_texture_mod(self, "^[brighten")
|
remove_texture_mod(self, "^[brighten")
|
||||||
self.passive = true
|
self.passive = true
|
||||||
|
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
pointable = false,
|
pointable = false,
|
||||||
collide_with_objects = false,
|
collide_with_objects = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
local acc = self.object:get_acceleration()
|
local acc = self.object:get_acceleration()
|
||||||
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
|
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.timer = 0
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
self.blinkstatus = false
|
self.blinkstatus = false
|
||||||
|
self.collide_with_objects = false
|
||||||
|
|
||||||
-- check existing nametag
|
-- check existing nametag
|
||||||
if not self.nametag then
|
if not self.nametag then
|
||||||
|
@ -3556,7 +3562,7 @@ local mob_step = function(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- mob plays random sound at times
|
-- mob plays random sound at times
|
||||||
if random(1, 70) == 1 then
|
if random(1, 100) == 1 then
|
||||||
mob_sound(self, "random", true)
|
mob_sound(self, "random", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3901,12 +3907,6 @@ minetest.register_entity(name, {
|
||||||
on_detach_child = mob_detach_child,
|
on_detach_child = mob_detach_child,
|
||||||
|
|
||||||
on_activate = function(self, staticdata, dtime)
|
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)
|
return mob_activate(self, staticdata, def, dtime)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -3925,6 +3925,289 @@ end
|
||||||
end -- END mobs:register_mob function
|
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
|
-- register arrow for shoot attack
|
||||||
function mobs:register_arrow(name, def)
|
function mobs:register_arrow(name, def)
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,8 @@ local path = minetest.get_modpath(minetest.get_current_modname())
|
||||||
-- Mob API
|
-- Mob API
|
||||||
dofile(path .. "/api.lua")
|
dofile(path .. "/api.lua")
|
||||||
|
|
||||||
-- Spawning Algorithm
|
|
||||||
dofile(path .. "/spawning.lua")
|
|
||||||
|
|
||||||
-- Rideable Mobs
|
-- Rideable Mobs
|
||||||
dofile(path .. "/mount.lua")
|
dofile(path .. "/mount.lua")
|
||||||
|
|
||||||
-- Mob Items
|
-- 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 = {
|
mobs_mc.spawn_height = {
|
||||||
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
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 boundaries (inclusive)
|
||||||
overworld_min = -64,-- -2999,
|
overworld_min = -2999,
|
||||||
overworld_max = 31000,
|
overworld_max = 31000,
|
||||||
|
|
||||||
-- Nether boundaries (inclusive)
|
-- Nether boundaries (inclusive)
|
||||||
nether_min = -29067,-- -3369,
|
nether_min = -3369,
|
||||||
nether_max = -28939,-- -3000,
|
nether_max = -3000,
|
||||||
|
|
||||||
-- End boundaries (inclusive)
|
-- End boundaries (inclusive)
|
||||||
end_min = -6200,
|
end_min = -6200,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--###################
|
--###################
|
||||||
--################### AGENT - seemingly unused
|
--################### AGENT
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator("mobs_mc")
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
|
@ -64,81 +64,7 @@ else
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Spawn on solid blocks at or below Sea level and the selected light level
|
-- Spawn on solid blocks at or below Sea level and the selected light level
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- daufinsyd
|
-- daufinsyd
|
||||||
-- My work is under the LGPL terms
|
-- 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
|
-- blaze.lua partial copy of mobs_mc/ghast.lua
|
||||||
|
|
||||||
local S = minetest.get_translator("mobs_mc")
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
@ -128,18 +128,7 @@ mobs:register_mob("mobs_mc:blaze", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- Blaze fireball
|
-- Blaze fireball
|
||||||
mobs:register_arrow("mobs_mc:blaze_fireball", {
|
mobs:register_arrow("mobs_mc:blaze_fireball", {
|
||||||
|
|
|
@ -100,34 +100,7 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
})
|
})
|
||||||
|
|
||||||
--spawn
|
--spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)
|
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
|
-- Spawning
|
||||||
mobs:spawn_specific(
|
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_mc:cow",
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn egg
|
-- spawn egg
|
||||||
mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)
|
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" },
|
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||||
attack_type = "explode",
|
attack_type = "explode",
|
||||||
|
|
||||||
--hssssssssssss
|
|
||||||
|
|
||||||
explosion_strength = 3,
|
explosion_strength = 3,
|
||||||
explosion_radius = 3.5,
|
explosion_radius = 3.5,
|
||||||
explosion_damage_radius = 3.5,
|
explosion_damage_radius = 3.5,
|
||||||
|
@ -140,9 +138,6 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
pathfinding = 1,
|
pathfinding = 1,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_creeper.b3d",
|
mesh = "mobs_mc_creeper.b3d",
|
||||||
|
|
||||||
--BOOM
|
|
||||||
|
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_mc_creeper.png",
|
{"mobs_mc_creeper.png",
|
||||||
"mobs_mc_creeper_charge.png"},
|
"mobs_mc_creeper_charge.png"},
|
||||||
|
@ -253,158 +248,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
glow = 3,
|
glow = 3,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)
|
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,
|
ignores_nametag = true,
|
||||||
do_custom = function(self)
|
do_custom = function(self)
|
||||||
mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple")
|
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
|
if self._portal_pos then
|
||||||
-- migrate old format
|
-- migrate old format
|
||||||
if type(self._portal_pos) == "string" then
|
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
|
--skip player if they have no data - log it
|
||||||
if not player_eye_height then
|
if not player_eye_height then
|
||||||
minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!")
|
minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!")
|
||||||
else
|
goto continue
|
||||||
|
|
||||||
--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
|
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -561,189 +562,11 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
|
|
||||||
|
|
||||||
-- End spawn
|
-- End spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
-- Overworld spawn
|
-- Overworld spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- Nether spawn (rare)
|
-- Nether spawn (rare)
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"mobs_mc:enderman",
|
|
||||||
"nether",
|
|
||||||
"ground",
|
|
||||||
{
|
|
||||||
"Nether"
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
7,
|
|
||||||
30,
|
|
||||||
27500,
|
|
||||||
4,
|
|
||||||
mobs_mc.spawn_height.nether_min,
|
|
||||||
mobs_mc.spawn_height.nether_max)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)
|
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: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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- fireball (projectile)
|
-- fireball (projectile)
|
||||||
mobs:register_arrow("mobs_mc:fireball", {
|
mobs:register_arrow("mobs_mc:fireball", {
|
||||||
|
|
|
@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", {
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Spawning disabled due to size issues <- what do you mean? -j4i
|
-- Spawning disabled due to size issues
|
||||||
-- TODO: Re-enable spawning
|
-- 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)
|
-- 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
|
--Spawn Function
|
||||||
mobs:spawn_specific(
|
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_mc:horse",
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
|
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
|
--spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)
|
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
|
local base_spawn_chance = 5000
|
||||||
|
|
||||||
-- Spawn ocelot
|
-- 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({
|
mobs:spawn({
|
||||||
name = "mobs_mc:ocelot",
|
name = "mobs_mc:ocelot",
|
||||||
nodes = mobs_mc.spawn.jungle,
|
nodes = mobs_mc.spawn.jungle,
|
||||||
|
@ -182,8 +163,8 @@ mobs:spawn({
|
||||||
min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
|
min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
|
||||||
max_height = mobs_mc.spawn_height.overworld_max,
|
max_height = mobs_mc.spawn_height.overworld_max,
|
||||||
on_spawn = function(self, pos)
|
on_spawn = function(self, pos)
|
||||||
Note: Minecraft has a 1/3 spawn failure rate.
|
--[[ Note: Minecraft has a 1/3 spawn failure rate.
|
||||||
In this mod it is emulated by reducing the spawn rate accordingly (see above).
|
In this mod it is emulated by reducing the spawn rate accordingly (see above). ]]
|
||||||
|
|
||||||
-- 1/7 chance to spawn 2 ocelot kittens
|
-- 1/7 chance to spawn 2 ocelot kittens
|
||||||
if pr:next(1,7) == 1 then
|
if pr:next(1,7) == 1 then
|
||||||
|
@ -226,7 +207,6 @@ mobs:spawn({
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
]]--
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture
|
-- 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
|
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome*
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)
|
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,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)
|
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: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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn egg
|
-- spawn egg
|
||||||
mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)
|
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)
|
mobs:register_mob("mobs_mc:killer_bunny", killer_bunny)
|
||||||
|
|
||||||
-- Mob spawning rules.
|
-- 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 = {
|
local spawn = {
|
||||||
name = "mobs_mc:rabbit",
|
name = "mobs_mc:rabbit",
|
||||||
neighbors = {"air"},
|
neighbors = {"air"},
|
||||||
|
@ -196,7 +165,6 @@ spawn_grass.on_spawn = function(self, pos)
|
||||||
self.object:set_properties({textures = self.base_texture})
|
self.object:set_properties({textures = self.base_texture})
|
||||||
end
|
end
|
||||||
mobs:spawn(spawn_grass)
|
mobs:spawn(spawn_grass)
|
||||||
]]--
|
|
||||||
|
|
||||||
-- Spawn egg
|
-- Spawn egg
|
||||||
mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)
|
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
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)
|
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:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
|
@ -139,195 +139,13 @@ table.insert(stray.drops, {
|
||||||
mobs:register_mob("mobs_mc:stray", stray)
|
mobs:register_mob("mobs_mc:stray", stray)
|
||||||
|
|
||||||
-- Overworld spawn
|
-- Overworld spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
|
|
||||||
-- Nether spawn
|
-- Nether spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"mobs_mc:skeleton",
|
|
||||||
"nether",
|
|
||||||
"ground",
|
|
||||||
{
|
|
||||||
"Nether"
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
7,
|
|
||||||
30,
|
|
||||||
10000,
|
|
||||||
3,
|
|
||||||
mobs_mc.spawn_height.nether_min,
|
|
||||||
mobs_mc.spawn_height.nether_max)
|
|
||||||
|
|
||||||
-- Stray spawn
|
-- Stray spawn
|
||||||
-- TODO: Spawn directly under the sky
|
-- TODO: Spawn directly under the sky
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
|
|
|
@ -94,20 +94,7 @@ mobs:register_mob("mobs_mc:witherskeleton", {
|
||||||
})
|
})
|
||||||
|
|
||||||
--spawn
|
--spawn
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"mobs_mc:witherskeleton",
|
|
||||||
"nether",
|
|
||||||
"ground",
|
|
||||||
{
|
|
||||||
"Nether"
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
7,
|
|
||||||
30,
|
|
||||||
5000,
|
|
||||||
5,
|
|
||||||
mobs_mc.spawn_height.nether_min,
|
|
||||||
mobs_mc.spawn_height.nether_max)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- 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 smin = mobs_mc.spawn_height.overworld_min
|
||||||
local smax = mobs_mc.spawn_height.water - 23
|
local smax = mobs_mc.spawn_height.water - 23
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax)
|
||||||
"mobs_mc:slime_tiny",
|
mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax)
|
||||||
"overworld",
|
mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- Magma cube
|
-- Magma cube
|
||||||
local magma_cube_big = {
|
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 mmin = mobs_mc.spawn_height.nether_min
|
||||||
local mmax = mobs_mc.spawn_height.nether_max
|
local mmax = mobs_mc.spawn_height.nether_max
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax)
|
||||||
"mobs_mc:magma_cube_tiny",
|
mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax)
|
||||||
"nether",
|
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax)
|
||||||
"ground",
|
|
||||||
{
|
|
||||||
"Nether"
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
minetest.LIGHT_MAX+1,
|
|
||||||
30,
|
|
||||||
15000,
|
|
||||||
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:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
|
||||||
"mobs_mc:magma_cube_small",
|
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
|
||||||
"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)
|
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
|
|
|
@ -87,158 +87,7 @@ cave_spider.sounds.base_pitch = 1.25
|
||||||
mobs:register_mob("mobs_mc:cave_spider", cave_spider)
|
mobs:register_mob("mobs_mc:cave_spider", cave_spider)
|
||||||
|
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0)
|
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
|
local water = mobs_mc.spawn_height.water
|
||||||
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
|
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0)
|
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: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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0)
|
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,
|
harmed_by_heal = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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_mc:villager_zombie",
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0)
|
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
|
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)
|
--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
|
-- spawn eggs
|
||||||
|
|
|
@ -232,34 +232,6 @@ end
|
||||||
mobs:register_mob("mobs_mc:dog", dog)
|
mobs:register_mob("mobs_mc:dog", dog)
|
||||||
|
|
||||||
-- Spawn
|
-- Spawn
|
||||||
mobs:spawn_specific(
|
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_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:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0)
|
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
|
-- Spawning
|
||||||
|
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
-- Baby zombie is 20 times less likely than regular zombies
|
-- Baby zombie is 20 times less likely than regular zombies
|
||||||
mobs:spawn_specific(
|
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_mc:baby_zombie",
|
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)
|
||||||
"overworld",
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- Spawn eggs
|
-- Spawn eggs
|
||||||
mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0)
|
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)
|
mobs:register_mob("mobs_mc:baby_pigman", baby_pigman)
|
||||||
|
|
||||||
-- Regular spawning in the Nether
|
-- Regular spawning in the Nether
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
-- Baby zombie is 20 times less likely than regular zombies
|
-- Baby zombie is 20 times less likely than regular zombies
|
||||||
mobs:spawn_specific(
|
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)
|
||||||
"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)
|
|
||||||
|
|
||||||
-- Spawning in Nether portals in the Overworld
|
-- 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
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0)
|
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
|
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 name = player:get_player_name()
|
||||||
local bars = mcl_bossbars.bars[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)
|
bar.color, bar.image = get_color_info(def.color, def.percentage)
|
||||||
if dynamic then
|
if def.dynamic then
|
||||||
for _, other in pairs(bars) do
|
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.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
|
if not other.count then
|
||||||
|
@ -55,7 +55,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(bars, bar)
|
table.insert(bars, bar)
|
||||||
if not dynamic then
|
if not def.dynamic then
|
||||||
bar.raw_color = def.color
|
bar.raw_color = def.color
|
||||||
bar.id = last_id + 1
|
bar.id = last_id + 1
|
||||||
last_id = bar.id
|
last_id = bar.id
|
||||||
|
@ -69,11 +69,10 @@ function mcl_bossbars.remove_bar(id)
|
||||||
mcl_bossbars.static[id] = nil
|
mcl_bossbars.static[id] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_bossbars.update_bar(id, def, priority)
|
function mcl_bossbars.update_bar(id, def)
|
||||||
local old = mcl_bossbars.static[id]
|
local old = mcl_bossbars.static[id]
|
||||||
old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage)
|
old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage)
|
||||||
old.text = def.text or old.text
|
old.text = def.text or old.text
|
||||||
old.priority = priority or old.priority
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_bossbars.update_boss(luaentity, name, color)
|
function mcl_bossbars.update_boss(luaentity, name, color)
|
||||||
|
@ -82,15 +81,14 @@ function mcl_bossbars.update_boss(luaentity, name, color)
|
||||||
text = luaentity.nametag,
|
text = luaentity.nametag,
|
||||||
percentage = math.floor(luaentity.health / luaentity.hp_max * 100),
|
percentage = math.floor(luaentity.health / luaentity.hp_max * 100),
|
||||||
color = color,
|
color = color,
|
||||||
|
dynamic = true,
|
||||||
}
|
}
|
||||||
if not bardef.text or bardef.text == "" then
|
if not bardef.text or bardef.text == "" then
|
||||||
bardef.text = name
|
bardef.text = name
|
||||||
end
|
end
|
||||||
local pos = object:get_pos()
|
for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do
|
||||||
for _, player in pairs(minetest.get_connected_players()) do
|
if obj:is_player() then
|
||||||
local d = vector.distance(pos, player:get_pos())
|
mcl_bossbars.add_bar(obj, bardef)
|
||||||
if d <= 80 then
|
|
||||||
mcl_bossbars.add_bar(player, bardef, true, d)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -117,7 +115,6 @@ minetest.register_globalstep(function()
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local bars = mcl_bossbars.bars[name]
|
local bars = mcl_bossbars.bars[name]
|
||||||
local huds = mcl_bossbars.huds[name]
|
local huds = mcl_bossbars.huds[name]
|
||||||
table.sort(bars, function(a, b) return a.priority < b.priority end)
|
|
||||||
local huds_new = {}
|
local huds_new = {}
|
||||||
local bars_new = {}
|
local bars_new = {}
|
||||||
local i = 0
|
local i = 0
|
||||||
|
|
|
@ -47,34 +47,28 @@
|
||||||
-- mesecon.rotate_rules_down(rules)
|
-- mesecon.rotate_rules_down(rules)
|
||||||
-- These functions return rules that have been rotated in the specific direction
|
-- 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
|
-- General
|
||||||
function mesecon.get_effector(nodename)
|
function mesecon.get_effector(nodename)
|
||||||
if registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and registered_nodes[nodename].mesecons.effector then
|
and minetest.registered_nodes[nodename].mesecons.effector then
|
||||||
return registered_nodes[nodename].mesecons.effector
|
return minetest.registered_nodes[nodename].mesecons.effector
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_receptor(nodename)
|
function mesecon.get_receptor(nodename)
|
||||||
if registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and registered_nodes[nodename].mesecons.receptor then
|
and minetest.registered_nodes[nodename].mesecons.receptor then
|
||||||
return registered_nodes[nodename].mesecons.receptor
|
return minetest.registered_nodes[nodename].mesecons.receptor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_conductor(nodename)
|
function mesecon.get_conductor(nodename)
|
||||||
if registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and registered_nodes[nodename].mesecons.conductor then
|
and minetest.registered_nodes[nodename].mesecons.conductor then
|
||||||
return registered_nodes[nodename].mesecons.conductor
|
return minetest.registered_nodes[nodename].mesecons.conductor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -109,14 +103,13 @@ end
|
||||||
|
|
||||||
-- Receptors
|
-- Receptors
|
||||||
-- Nodes that can power mesecons
|
-- Nodes that can power mesecons
|
||||||
local function is_receptor_on(nodename)
|
function mesecon.is_receptor_on(nodename)
|
||||||
local receptor = mesecon.get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
if receptor and receptor.state == mesecon.state.on then
|
if receptor and receptor.state == mesecon.state.on then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
mesecon.is_receptor_on = is_receptor_on
|
|
||||||
|
|
||||||
function mesecon.is_receptor_off(nodename)
|
function mesecon.is_receptor_off(nodename)
|
||||||
local receptor = mesecon.get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
|
@ -134,7 +127,7 @@ function mesecon.is_receptor(nodename)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function receptor_get_rules(node)
|
function mesecon.receptor_get_rules(node)
|
||||||
local receptor = mesecon.get_receptor(node.name)
|
local receptor = mesecon.get_receptor(node.name)
|
||||||
if receptor then
|
if receptor then
|
||||||
local rules = receptor.rules
|
local rules = receptor.rules
|
||||||
|
@ -147,7 +140,6 @@ local function receptor_get_rules(node)
|
||||||
|
|
||||||
return mesecon.rules.default
|
return mesecon.rules.default
|
||||||
end
|
end
|
||||||
mesecon.receptor_get_rules = receptor_get_rules
|
|
||||||
|
|
||||||
-- Effectors
|
-- Effectors
|
||||||
-- Nodes that can be powered by mesecons
|
-- Nodes that can be powered by mesecons
|
||||||
|
@ -194,7 +186,7 @@ end
|
||||||
|
|
||||||
-- Activation:
|
-- Activation:
|
||||||
mesecon.queue:add_function("activate", function (pos, rulename)
|
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
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -206,7 +198,7 @@ end)
|
||||||
|
|
||||||
function mesecon.activate(pos, node, rulename, depth)
|
function mesecon.activate(pos, node, rulename, depth)
|
||||||
if rulename == nil then
|
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)
|
mesecon.activate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -217,7 +209,7 @@ end
|
||||||
|
|
||||||
-- Deactivation
|
-- Deactivation
|
||||||
mesecon.queue:add_function("deactivate", function (pos, rulename)
|
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
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -229,7 +221,7 @@ end)
|
||||||
|
|
||||||
function mesecon.deactivate(pos, node, rulename, depth)
|
function mesecon.deactivate(pos, node, rulename, depth)
|
||||||
if rulename == nil then
|
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)
|
mesecon.deactivate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -240,7 +232,7 @@ end
|
||||||
|
|
||||||
-- Change
|
-- Change
|
||||||
mesecon.queue:add_function("change", function (pos, rulename, changetype)
|
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
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -252,7 +244,7 @@ end)
|
||||||
|
|
||||||
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
||||||
if rulename == nil then
|
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)
|
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -364,15 +356,15 @@ end
|
||||||
-- some more general high-level stuff
|
-- some more general high-level stuff
|
||||||
|
|
||||||
function mesecon.is_power_on(pos, rulename)
|
function mesecon.is_power_on(pos, rulename)
|
||||||
local node = get_node_force(pos)
|
local node = mesecon.get_node_force(pos)
|
||||||
if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then
|
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.is_power_off(pos, rulename)
|
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
|
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -389,7 +381,7 @@ function mesecon.turnon(pos, link)
|
||||||
local depth = 1
|
local depth = 1
|
||||||
while frontiers[1] do
|
while frontiers[1] do
|
||||||
local f = table.remove(frontiers, 1)
|
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
|
if not node then
|
||||||
-- Area does not exist; do nothing
|
-- Area does not exist; do nothing
|
||||||
|
@ -397,10 +389,10 @@ function mesecon.turnon(pos, link)
|
||||||
local rules = mesecon.conductor_get_rules(node)
|
local rules = mesecon.conductor_get_rules(node)
|
||||||
|
|
||||||
-- Call turnon on neighbors
|
-- 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)
|
local np = vector.add(f.pos, r)
|
||||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
insert(frontiers, {pos = np, link = l})
|
table.insert(frontiers, {pos = np, link = l})
|
||||||
end
|
end
|
||||||
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
|
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
||||||
-- Call turnon on neighbors
|
-- Call turnon on neighbors
|
||||||
-- Warning: A LOT of nodes need to be looked at for this to work
|
-- 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)
|
local np = vector.add(f.pos, r)
|
||||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
local nlink = copy(l)
|
local nlink = table.copy(l)
|
||||||
nlink.spread = false
|
nlink.spread = false
|
||||||
insert(frontiers, {pos = np, link = nlink})
|
table.insert(frontiers, {pos = np, link = nlink})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -451,33 +443,33 @@ function mesecon.turnoff(pos, link)
|
||||||
local depth = 1
|
local depth = 1
|
||||||
while frontiers[1] do
|
while frontiers[1] do
|
||||||
local f = table.remove(frontiers, 1)
|
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
|
if not node then
|
||||||
-- No-op
|
-- No-op
|
||||||
elseif mesecon.is_conductor_on(node, f.link) then
|
elseif mesecon.is_conductor_on(node, f.link) then
|
||||||
local rules = mesecon.conductor_get_rules(node)
|
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)
|
local np = vector.add(f.pos, r)
|
||||||
|
|
||||||
-- Check if an onstate receptor is connected. If that is the case,
|
-- Check if an onstate receptor is connected. If that is the case,
|
||||||
-- abort this turnoff process by returning false. `receptor_off` will
|
-- abort this turnoff process by returning false. `receptor_off` will
|
||||||
-- discard all the changes that we made in the voxelmanip:
|
-- discard all the changes that we made in the voxelmanip:
|
||||||
for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
|
for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
|
||||||
if is_receptor_on(get_node_force(np).name) then
|
if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Call turnoff on neighbors
|
-- Call turnoff on neighbors
|
||||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
insert(frontiers, {pos = np, link = l})
|
table.insert(frontiers, {pos = np, link = l})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
||||||
elseif mesecon.is_effector(node.name) then
|
elseif mesecon.is_effector(node.name) then
|
||||||
insert(signals, {
|
table.insert(signals, {
|
||||||
pos = f.pos,
|
pos = f.pos,
|
||||||
node = node,
|
node = node,
|
||||||
link = f.link,
|
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
|
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
||||||
-- Call turnoff on neighbors
|
-- Call turnoff on neighbors
|
||||||
-- Warning: A LOT of nodes need to be looked at for this to work
|
-- Warning: A LOT of nodes need to be looked at for this to work
|
||||||
local fpos = f.pos
|
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
||||||
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
local np = vector.add(f.pos, r)
|
||||||
local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z}
|
local n = mesecon.get_node_force(np)
|
||||||
local n = get_node_force(np)
|
if mesecon.is_receptor_on(n.name) then
|
||||||
if n and is_receptor_on(n.name) then
|
local receptorrules = mesecon.receptor_get_rules(n)
|
||||||
local receptorrules = receptor_get_rules(n)
|
|
||||||
for _, rr in pairs(receptorrules) do
|
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
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do
|
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
local nlink = copy(l)
|
local nlink = table.copy(l)
|
||||||
nlink.spread = false
|
nlink.spread = false
|
||||||
insert(frontiers, {pos = np, link = nlink})
|
table.insert(frontiers, {pos = np, link = nlink})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -511,7 +502,7 @@ function mesecon.turnoff(pos, link)
|
||||||
depth = depth + 1
|
depth = depth + 1
|
||||||
end
|
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)
|
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
|
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)
|
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`
|
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
|
||||||
function mesecon.rules_link_rule_all(output, rule)
|
function mesecon.rules_link_rule_all(output, rule)
|
||||||
local input = vector.add(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)
|
local inputrules = mesecon.get_any_inputrules(inputnode)
|
||||||
if not inputrules then
|
if not inputrules then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
local rules = {}
|
local rules = {}
|
||||||
|
|
||||||
for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do
|
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
||||||
-- Check if input accepts from output
|
-- Check if input accepts from output
|
||||||
if equals(vector.add(input, inputrule), output) then
|
if vector.equals(vector.add(input, inputrule), output) then
|
||||||
local newrule = copy(inputrule)
|
local newrule = table.copy(inputrule)
|
||||||
newrule.spread = rule.spread
|
newrule.spread = rule.spread
|
||||||
insert(rules, newrule)
|
table.insert(rules, newrule)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -548,19 +539,19 @@ end
|
||||||
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
|
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
|
||||||
function mesecon.rules_link_rule_all_inverted(input, rule)
|
function mesecon.rules_link_rule_all_inverted(input, rule)
|
||||||
local output = vector.add(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)
|
local outputrules = mesecon.get_any_outputrules(outputnode)
|
||||||
if not outputrules then
|
if not outputrules then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
local rules = {}
|
local rules = {}
|
||||||
|
|
||||||
for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do
|
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
|
||||||
if equals(vector.add(output, outputrule), input) then
|
if vector.equals(vector.add(output, outputrule), input) then
|
||||||
local newrule = copy(outputrule)
|
local newrule = table.copy(outputrule)
|
||||||
newrule = invertRule(newrule)
|
newrule = mesecon.invertRule(newrule)
|
||||||
newrule.spread = rule.spread
|
newrule.spread = rule.spread
|
||||||
insert(rules, newrule)
|
table.insert(rules, newrule)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
|
@ -571,7 +562,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||||
if depth > 1 then
|
if depth > 1 then
|
||||||
return false, false
|
return false, false
|
||||||
end
|
end
|
||||||
local node = get_node_force(pos)
|
local node = mesecon.get_node_force(pos)
|
||||||
local rules = mesecon.get_any_inputrules(node)
|
local rules = mesecon.get_any_inputrules(node)
|
||||||
if not rules then
|
if not rules then
|
||||||
return false, false
|
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 function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
||||||
local spread = false
|
local spread = false
|
||||||
for _, rname in pairs(rulenames) do
|
for _, rname in ipairs(rulenames) do
|
||||||
local np = vector.add(pos, rname)
|
local np = vector.add(pos, rname)
|
||||||
local nn = get_node_force(np)
|
local nn = mesecon.get_node_force(np)
|
||||||
if (mesecon.is_conductor_on (nn, invertRule(rname))
|
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
|
||||||
or is_receptor_on (nn.name)) then
|
or mesecon.is_receptor_on (nn.name)) then
|
||||||
if not equals(home_pos, np) then
|
if not vector.equals(home_pos, np) then
|
||||||
local rulez = mesecon.get_any_outputrules(nn)
|
local rulez = mesecon.get_any_outputrules(nn)
|
||||||
local spread_tmp = false
|
local spread_tmp = false
|
||||||
for r=1, #rulez do
|
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
|
if rulez[r].spread then
|
||||||
spread_tmp = true
|
spread_tmp = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if depth == 0 or spread_tmp then
|
if depth == 0 or spread_tmp then
|
||||||
insert(sourcepos, np)
|
table.insert(sourcepos, np)
|
||||||
if spread_tmp then
|
if spread_tmp then
|
||||||
spread = true
|
spread = true
|
||||||
end
|
end
|
||||||
|
@ -621,7 +612,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||||
|
|
||||||
local spread = false
|
local spread = false
|
||||||
if not rule then
|
if not rule then
|
||||||
for _, rule in pairs(mesecon.flattenrules(rules)) do
|
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||||
local spread_temp
|
local spread_temp
|
||||||
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
|
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
|
||||||
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
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({
|
minetest.register_craft({
|
||||||
type = 'shapeless',
|
type = 'shapeless',
|
||||||
output = 'mcl_core:mossycobble',
|
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 S = minetest.get_translator("mcl_core")
|
||||||
|
|
||||||
local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil
|
local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil
|
||||||
|
@ -48,166 +48,6 @@ local register_tree_trunk = function(subname, description_trunk, description_bar
|
||||||
})
|
})
|
||||||
end
|
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)
|
local register_wooden_planks = function(subname, description, tiles)
|
||||||
minetest.register_node("mcl_core:"..subname, {
|
minetest.register_node("mcl_core:"..subname, {
|
||||||
description = description,
|
description = description,
|
||||||
|
@ -386,4 +226,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from
|
||||||
-- Node aliases
|
-- Node aliases
|
||||||
|
|
||||||
minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree")
|
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
|
_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", {
|
minetest.register_craftitem("mcl_end:crystal", {
|
||||||
inventory_image = "mcl_end_crystal_item.png",
|
inventory_image = "mcl_end_crystal_item.png",
|
||||||
description = S("End Crystal"),
|
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
|
-- TODO: whenever it becomes possible to fully implement kelp without the
|
||||||
-- plantlike_rooted limitation, please update accordingly.
|
-- 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.
|
-- 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.
|
-- However, because of the plantlike_rooted hack, we'll just allow it for now.
|
||||||
|
|
||||||
|
@ -194,18 +191,17 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- Converts param2 to kelp height.
|
-- 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)
|
function kelp.get_height(param2)
|
||||||
return math_floor(param2 / 16) + math_floor(param2 % 16 / 8)
|
return math_floor(param2 / 16)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Obtain pos and node of the tip of kelp.
|
-- Obtain pos and node of the tip of kelp.
|
||||||
function kelp.get_tip(pos, height)
|
function kelp.get_tip(pos, param2)
|
||||||
-- Optional params: height
|
-- Optional params: param2
|
||||||
local height = height or kelp.get_height(mt_get_node(pos).param2)
|
local height = kelp.get_height(param2 or mt_get_node(pos).param2)
|
||||||
local pos_tip = {x=pos.x, y=pos.y+height+1, z=pos.z}
|
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
|
return pos_tip, mt_get_node(pos_tip), height
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -214,7 +210,7 @@ end
|
||||||
function kelp.find_unsubmerged(pos, node, height)
|
function kelp.find_unsubmerged(pos, node, height)
|
||||||
-- Optional params: node, height
|
-- Optional params: node, height
|
||||||
local node = node or mt_get_node(pos)
|
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 walk_pos = {x=pos.x, z=pos.z}
|
||||||
local y = pos.y
|
local y = pos.y
|
||||||
|
@ -231,8 +227,7 @@ end
|
||||||
|
|
||||||
-- Obtain next param2.
|
-- Obtain next param2.
|
||||||
function kelp.next_param2(param2)
|
function kelp.next_param2(param2)
|
||||||
-- param2 max value is 255, so adding to 256 causes overflow.
|
return param2+16 - param2 % 16
|
||||||
return math_min(param2+16 - param2 % 16, 255);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,7 +311,7 @@ function kelp.init_timer(pos, pos_hash)
|
||||||
end
|
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)
|
function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing)
|
||||||
-- Modified params: node
|
-- Modified params: node
|
||||||
-- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing
|
-- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing
|
||||||
|
@ -372,9 +367,9 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- Drops the items for detached kelps.
|
-- Drops the items for detached kelps.
|
||||||
function kelp.detach_drop(pos, height)
|
function kelp.detach_drop(pos, param2)
|
||||||
-- Optional params: height
|
-- Optional params: param2
|
||||||
local height = height or kelp.get_height(mt_get_node(pos).param2)
|
local height = kelp.get_height(param2 or mt_get_node(pos).param2)
|
||||||
local y = pos.y
|
local y = pos.y
|
||||||
local walk_pos = {x=pos.x, z=pos.z}
|
local walk_pos = {x=pos.x, z=pos.z}
|
||||||
for i=1,height do
|
for i=1,height do
|
||||||
|
@ -389,18 +384,17 @@ end
|
||||||
-- Synonymous to digging the kelp.
|
-- Synonymous to digging the kelp.
|
||||||
-- NOTE: this is intended for whenever kelp truly becomes segmented plants
|
-- NOTE: this is intended for whenever kelp truly becomes segmented plants
|
||||||
-- instead of rooted to the floor. Don't try to remove dig_pos.
|
-- instead of rooted to the floor. Don't try to remove dig_pos.
|
||||||
function kelp.detach_dig(dig_pos, pos, drop, node, height)
|
function kelp.detach_dig(dig_pos, pos, node, drop)
|
||||||
-- Optional params: drop, node, height
|
-- Optional params: drop
|
||||||
|
|
||||||
local node = node or mt_get_node(pos)
|
local param2 = node.param2
|
||||||
local height = height or kelp.get_height(node.param2)
|
|
||||||
-- pos.y points to the surface, offset needed to point to the first kelp.
|
-- pos.y points to the surface, offset needed to point to the first kelp.
|
||||||
local new_height = dig_pos.y - (pos.y+1)
|
local new_height = dig_pos.y - (pos.y+1)
|
||||||
|
|
||||||
-- Digs the entire kelp.
|
-- Digs the entire kelp.
|
||||||
if new_height <= 0 then
|
if new_height <= 0 then
|
||||||
if drop then
|
if drop then
|
||||||
kelp.detach_drop(dig_pos, height)
|
kelp.detach_drop(dig_pos, param2)
|
||||||
end
|
end
|
||||||
mt_set_node(pos, {
|
mt_set_node(pos, {
|
||||||
name=mt_registered_nodes[node.name].node_dig_prediction,
|
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.
|
-- Digs the kelp beginning at a height.
|
||||||
else
|
else
|
||||||
if drop then
|
if drop then
|
||||||
kelp.detach_drop(dig_pos, height - new_height)
|
kelp.detach_drop(dig_pos, param2 - new_height)
|
||||||
end
|
end
|
||||||
mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height})
|
mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height})
|
||||||
end
|
end
|
||||||
|
@ -422,7 +416,7 @@ end
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
function kelp.surface_on_dig(pos, node, digger)
|
function kelp.surface_on_dig(pos, node, digger)
|
||||||
kelp.detach_dig(pos, pos, true, node)
|
kelp.detach_dig(pos, pos, node, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -436,11 +430,11 @@ function kelp.surface_on_timer(pos)
|
||||||
local pos_hash
|
local pos_hash
|
||||||
|
|
||||||
-- Update detahed kelps
|
-- Update detahed kelps
|
||||||
local dig_pos,_, height = kelp.find_unsubmerged(pos, node)
|
local dig_pos = kelp.find_unsubmerged(pos, node)
|
||||||
if dig_pos then
|
if dig_pos then
|
||||||
pos_hash = mt_hash_node_position(pos)
|
pos_hash = mt_hash_node_position(pos)
|
||||||
mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true)
|
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)
|
kelp.store_age(kelp.roll_init_age(), pos, pos_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -469,7 +463,7 @@ function kelp.surface_on_destruct(pos)
|
||||||
|
|
||||||
-- on_falling callback. Activated by pistons for falling nodes too.
|
-- on_falling callback. Activated by pistons for falling nodes too.
|
||||||
if kelp.is_falling(pos, node) then
|
if kelp.is_falling(pos, node) then
|
||||||
kelp.detach_drop(pos, kelp.get_height(node.param2))
|
kelp.detach_drop(pos, node.param2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Removes position from queue
|
-- Removes position from queue
|
||||||
|
@ -480,7 +474,7 @@ end
|
||||||
|
|
||||||
function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta)
|
function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta)
|
||||||
-- Pistons moving falling nodes will have already activated on_falling callback.
|
-- 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
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -524,7 +518,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
||||||
end
|
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
|
-- Kelp must also be placed on the top/tip side of the surface/kelp
|
||||||
if pos_under.y >= pos_above.y then
|
if pos_under.y >= pos_above.y then
|
||||||
return itemstack
|
return itemstack
|
||||||
|
@ -532,33 +526,31 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
||||||
|
|
||||||
-- When placed on kelp.
|
-- When placed on kelp.
|
||||||
if mt_get_item_group(nu_name, "kelp") == 1 then
|
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, node_under.param2)
|
||||||
pos_tip,node_tip = kelp.get_tip(pos_under, height)
|
|
||||||
def_tip = mt_registered_nodes[node_tip.name]
|
def_tip = mt_registered_nodes[node_tip.name]
|
||||||
|
|
||||||
-- When placed on surface.
|
-- When placed on surface.
|
||||||
else
|
else
|
||||||
new_surface = false
|
new_kelp = false
|
||||||
for _,surface in pairs(kelp.surfaces) do
|
for _,surface in pairs(kelp.surfaces) do
|
||||||
if nu_name == surface.nodename then
|
if nu_name == surface.nodename then
|
||||||
node_under.name = "mcl_ocean:kelp_" ..surface.name
|
node_under.name = "mcl_ocean:kelp_" ..surface.name
|
||||||
node_under.param2 = 0
|
node_under.param2 = 0
|
||||||
new_surface = true
|
new_kelp = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Surface must support kelp
|
-- Surface must support kelp
|
||||||
if not new_surface then
|
if not new_kelp then
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
pos_tip = pos_above
|
pos_tip = pos_above
|
||||||
node_tip = mt_get_node(pos_above)
|
node_tip = mt_get_node(pos_above)
|
||||||
def_tip = mt_registered_nodes[node_tip.name]
|
def_tip = mt_registered_nodes[node_tip.name]
|
||||||
height = 0
|
|
||||||
end
|
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 downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip)
|
||||||
local submerged = kelp.is_submerged(node_tip)
|
local submerged = kelp.is_submerged(node_tip)
|
||||||
if not submerged then
|
if not submerged then
|
||||||
|
@ -570,19 +562,14 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
|
||||||
if def_node.sounds then
|
if def_node.sounds then
|
||||||
mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true)
|
mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true)
|
||||||
end
|
end
|
||||||
-- TODO: get rid of rooted plantlike hack
|
kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing)
|
||||||
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
|
|
||||||
if not mt_is_creative_enabled(player_name) then
|
if not mt_is_creative_enabled(player_name) then
|
||||||
itemstack:take_item()
|
itemstack:take_item()
|
||||||
end
|
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)
|
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_age(pos_under, nil, pos_hash)
|
||||||
kelp.init_timer(pos_under, pos_hash)
|
kelp.init_timer(pos_under, pos_hash)
|
||||||
else
|
else
|
||||||
|
|
|
@ -490,12 +490,10 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
|
|
||||||
if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then
|
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
|
local pos1, pos2, pos = 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(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(p))
|
minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = pos, pos1 = pos1, pos2 = pos2, name=name, obj=obj})
|
||||||
minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = p, pos1 = pos1, pos2 = pos2, name=name, obj=obj})
|
return
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal")
|
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:
|
-- 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_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_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
|
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)}
|
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)}
|
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
|
-- 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", {
|
minetest.register_tool("mcl_tools:axe_wood", {
|
||||||
description = S("Wooden Axe"),
|
description = S("Wooden Axe"),
|
||||||
_doc_items_longdesc = axe_longdesc,
|
_doc_items_longdesc = axe_longdesc,
|
||||||
|
@ -415,7 +365,6 @@ minetest.register_tool("mcl_tools:axe_wood", {
|
||||||
damage_groups = {fleshy=7},
|
damage_groups = {fleshy=7},
|
||||||
punch_attack_uses = 30,
|
punch_attack_uses = 30,
|
||||||
},
|
},
|
||||||
on_place = make_stripped_trunk,
|
|
||||||
sound = { breaks = "default_tool_breaks" },
|
sound = { breaks = "default_tool_breaks" },
|
||||||
_repair_material = "group:wood",
|
_repair_material = "group:wood",
|
||||||
_mcl_toollike_wield = true,
|
_mcl_toollike_wield = true,
|
||||||
|
@ -435,7 +384,6 @@ minetest.register_tool("mcl_tools:axe_stone", {
|
||||||
damage_groups = {fleshy=9},
|
damage_groups = {fleshy=9},
|
||||||
punch_attack_uses = 66,
|
punch_attack_uses = 66,
|
||||||
},
|
},
|
||||||
on_place = make_stripped_trunk,
|
|
||||||
sound = { breaks = "default_tool_breaks" },
|
sound = { breaks = "default_tool_breaks" },
|
||||||
_repair_material = "mcl_core:cobble",
|
_repair_material = "mcl_core:cobble",
|
||||||
_mcl_toollike_wield = true,
|
_mcl_toollike_wield = true,
|
||||||
|
@ -456,7 +404,6 @@ minetest.register_tool("mcl_tools:axe_iron", {
|
||||||
damage_groups = {fleshy=9},
|
damage_groups = {fleshy=9},
|
||||||
punch_attack_uses = 126,
|
punch_attack_uses = 126,
|
||||||
},
|
},
|
||||||
on_place = make_stripped_trunk,
|
|
||||||
sound = { breaks = "default_tool_breaks" },
|
sound = { breaks = "default_tool_breaks" },
|
||||||
_repair_material = "mcl_core:iron_ingot",
|
_repair_material = "mcl_core:iron_ingot",
|
||||||
_mcl_toollike_wield = true,
|
_mcl_toollike_wield = true,
|
||||||
|
@ -476,7 +423,6 @@ minetest.register_tool("mcl_tools:axe_gold", {
|
||||||
damage_groups = {fleshy=7},
|
damage_groups = {fleshy=7},
|
||||||
punch_attack_uses = 17,
|
punch_attack_uses = 17,
|
||||||
},
|
},
|
||||||
on_place = make_stripped_trunk,
|
|
||||||
sound = { breaks = "default_tool_breaks" },
|
sound = { breaks = "default_tool_breaks" },
|
||||||
_repair_material = "mcl_core:gold_ingot",
|
_repair_material = "mcl_core:gold_ingot",
|
||||||
_mcl_toollike_wield = true,
|
_mcl_toollike_wield = true,
|
||||||
|
@ -496,7 +442,6 @@ minetest.register_tool("mcl_tools:axe_diamond", {
|
||||||
damage_groups = {fleshy=9},
|
damage_groups = {fleshy=9},
|
||||||
punch_attack_uses = 781,
|
punch_attack_uses = 781,
|
||||||
},
|
},
|
||||||
on_place = make_stripped_trunk,
|
|
||||||
sound = { breaks = "default_tool_breaks" },
|
sound = { breaks = "default_tool_breaks" },
|
||||||
_repair_material = "mcl_core:diamond",
|
_repair_material = "mcl_core:diamond",
|
||||||
_mcl_toollike_wield = true,
|
_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
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if minetest.registered_chatcommands["kill"] then
|
mcl_commands.override_command("kill", {
|
||||||
minetest.unregister_chatcommand("kill")
|
func = function(cmd)
|
||||||
end
|
cmd:sub("", {
|
||||||
minetest.register_chatcommand("kill", {
|
func = function(name)
|
||||||
params = S("[<name>]"),
|
return handle_kill_command(name, name)
|
||||||
description = S("Kill player or yourself"),
|
end,
|
||||||
privs = {server=true},
|
})
|
||||||
func = function(name, param)
|
cmd:sub(":target:username", {
|
||||||
if(param == "") then
|
func = function(name, target)
|
||||||
-- Selfkill
|
return handle_kill_command(name, target)
|
||||||
return handle_kill_command(name, name)
|
end,
|
||||||
else
|
})
|
||||||
return handle_kill_command(name, param)
|
|
||||||
end
|
|
||||||
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 def = {}
|
||||||
local time = 0
|
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
|
-- converts yaw to degrees
|
||||||
local function degrees(rad)
|
local function degrees(rad)
|
||||||
return rad * 180.0 / math.pi
|
return rad * 180.0 / math.pi
|
||||||
end
|
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 dir_to_pitch = function(dir)
|
||||||
local dir2 = vector.normalize(dir)
|
local dir2 = vector.normalize(dir)
|
||||||
local xz = math.abs(dir.x) + math.abs(dir.z)
|
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
|
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)
|
minetest.register_globalstep(function(dtime)
|
||||||
|
|
||||||
time = time + dtime
|
time = time + dtime
|
||||||
|
|
||||||
for _,player in pairs(get_connected_players()) do
|
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
|
if parent then
|
||||||
local parent_yaw = degrees(parent:get_yaw())
|
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("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))
|
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||||
elseif controls.sneak then
|
elseif controls.sneak then
|
||||||
-- controls head pitch when sneaking
|
-- controls head pitch when sneaking
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
|
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
|
||||||
-- sets eye height, and nametag color accordingly
|
-- 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
|
-- sneaking body conrols
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
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
|
elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then
|
||||||
-- set head pitch and yaw when swimming
|
-- 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))
|
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
|
-- 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
|
-- 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))
|
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
|
else
|
||||||
-- sets eye height, and nametag color accordingly
|
-- 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("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))
|
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0))
|
||||||
|
|