Compare commits

..

9 Commits

226 changed files with 1750 additions and 13371 deletions

1
API.md
View File

@ -41,7 +41,6 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
* Beds: `ITEMS/mcl_beds`
* Buckets: `ITEMS/mcl_buckets`
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
* Campfires: `ITEMS/mcl_campfires`
### Mobs
* Mobs: `ENTITIES/mcl_mobs`

View File

@ -2,8 +2,8 @@
So you want to contribute to MineClone2?
Wow, thank you! :-)
MineClone2 is maintained by AncientMariner and Nicu. If you have any
problems or questions, contact us on Discord/Matrix (See Links section below).
MineClone2 is maintained by Nicu and Cora. If you have any
problems or questions, contact us (See Links section below).
You can help with MineClone2's development in many different ways,
whether you're a programmer or not.
@ -240,7 +240,7 @@ work causes problems, we ask you fix the issues as soon as possible.
### Changing Gameplay
Pull Requests that change gameplay have to be properly researched and
need to state their sources. These PRs also need the maintainer's approval
need to state their sources. These PRs also need Fleckenstein's approval
before they are merged.
You can use these sources:
@ -375,7 +375,7 @@ merged.
- Resolving conflicts and problems within the community
#### Current maintainers
* AncientMariner - responsible for gameplay review, publishing releases,
* Cora - responsible for gameplay review, publishing releases,
technical guidelines
* Nicu - responsible for community related issues

View File

@ -99,10 +99,6 @@
* Gregor Parzefall
* Wbjitscool
* b3nderman
* CyberMango
* gldrk
* SmokeyDope
* atomdmac
## MineClone5
* kay27
@ -190,7 +186,6 @@
* snowyu
* 3raven
* SakuraRiu
* anarquimico
## Funders
* 40W

View File

@ -1,5 +1,3 @@
### Standard Release
#File to document release steps with a view to evolving into a script
#Update CREDITS.md
@ -21,55 +19,4 @@ git push origin 0.82.0
#Update version in game.conf to -SNAPSHOT
git commit -m "Post-release set version 0.82.0-SNAPSHOT"
### Hotfix Release
##### Prepare release branch
When hotfixing, you should never release new features. Any new code increases risk of new bugs which has additional testing/release concerns.
To mitigate this, you just release the last release, and the relevant bug fix. For this, we do the following:
* Create release branch from the last release tag, push it:
git checkout -b release/0.82.1 0.82.0
git push origin release/0.82.1
##### Prepare feature branch and fix
* Create feature branch from that release branch (can review it to check only fix is there, nothing else, and use to also merge into master separately)
git checkout -b hotfix_bug_1_branch
* Fix crash/serious bug and commit
* Push branch and create pr to the release and also the master branch (Do not rebase, to reduce merge conflict risk. Do not delete after first merge or it needs to be repushed)
##### Update version and tag the release
* After all fixes are in release branch, pull it locally (best to avoid a merge conflict as feature branch will need to be merged into master also, which already changed version):
* Update version in game.conf to hotfix version and commit it. Example: version=0.82.1
* Tag it, push tag and branch:
git tag 0.82.1
git push origin 0.82.1
git push origin release/0.82.1
Note: If you have to do more than 1 hotfix release, can do it on the same release branch.
### Release via ContentDB
* Go to MineClone2 page (https://content.minetest.net/packages/Wuzzy/mineclone2/)
* Click +Release
* Enter the release tag number in the title and Git reference box. For example (without quotes): "0.82.1"
* In the minimum minetest version, put the oldest supported version (as of 14/02/2023 it is 5.5), leave the Maximum minetest version blank
* Click save. Release is now live.
##### Inform people
* Add a comment to the forum post with the release number and what is involved, and maintainer will update main post.
* Add a comment in Discord announcement
git commit -m "Post-release set version 0.82.0-SNAPSHOT"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -556,11 +556,6 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
end
end
local is_immortal = target:get_armor_groups().immortal or 0
if is_immortal>0 then
return
end
local hp = target:get_hp()
if hp > 0 then
@ -1016,20 +1011,3 @@ function mcl_util.check_position_protection(position, player)
return false
end
local palette_indexes = {grass_palette_index = 0, foliage_palette_index = 0, water_palette_index = 0}
function mcl_util.get_palette_indexes_from_pos(pos)
local biome_data = minetest.get_biome_data(pos)
local biome = biome_data.biome
local biome_name = minetest.get_biome_name(biome)
local reg_biome = minetest.registered_biomes[biome_name]
if reg_biome and reg_biome._mcl_grass_palette_index and reg_biome._mcl_foliage_palette_index and reg_biome._mcl_water_palette_index then
local gpi = reg_biome._mcl_grass_palette_index
local fpi = reg_biome._mcl_foliage_palette_index
local wpi = reg_biome._mcl_water_palette_index
local palette_indexes = {grass_palette_index = gpi, foliage_palette_index = fpi, water_palette_index = wpi}
return palette_indexes
else
return palette_indexes
end
end

View File

@ -2,7 +2,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
-- Template rail function
local function register_rail(itemstring, tiles, def_extras, creative)
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=0,destroy_by_lava_flow=0, transport=1}
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1}
if creative == false then
groups.not_in_creative_inventory = 1
end

View File

@ -4,7 +4,6 @@ local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
-- API for Mobs Redo: MineClone 2 Edition (MRM)
local PATHFINDING = "gowp"
local CRASH_WARN_FREQUENCY = 60
-- Localize
local S = minetest.get_translator("mcl_mobs")
@ -136,8 +135,8 @@ function mob_class:mob_activate(staticdata, def, dtime)
end
end
--If textures in definition change, reload textures
if not self.base_texture or (def.textures and table.indexof(def.textures, self.base_texture) == -1) then
if not self.base_texture then
-- compatiblity with old simple mobs textures
if type(def.textures[1]) == "string" then
def.textures = {def.textures}
@ -318,7 +317,7 @@ local function update_timers (self, dtime)
return true
end
-- attack timer. Not anymore, it seems. Used for also occassionally processing mob step too!
-- attack timer
self.timer = self.timer + dtime
if self.state ~= "attack" and self.state ~= PATHFINDING then
@ -358,15 +357,14 @@ function mob_class:outside_limits()
end
end
local function on_step_work (self, dtime)
-- main mob function
function mob_class:on_step(dtime)
local pos = self.object:get_pos()
if not pos then return end
if self:check_despawn(pos, dtime) then return true end
if self:outside_limits() then return end
-- Start: Death/damage processing
-- All damage needs to be undertaken at the start. We need to exit processing if the mob dies.
if self:check_death_and_slow_mob() then
--minetest.log("action", "Mob is dying: ".. tostring(self.name))
-- Do we abandon out of here now?
@ -377,105 +375,64 @@ local function on_step_work (self, dtime)
if not self.fire_resistant then
mcl_burning.tick(self.object, dtime, self)
if not self.object:get_pos() then return end -- mcl_burning.tick may remove object immediately
if self:check_for_death("fire", {type = "fire"}) then
return true
end
-- mcl_burning.tick may remove object immediately
if not self.object:get_pos() then return end
end
if self:env_damage (dtime, pos) then return end
if self.state == "die" then return end
-- End: Death/damage processing
self:check_water_flow()
self:env_danger_movement_checks (dtime)
if mobs_debug then self:update_tag() end
self:follow_flop() -- Mob following code.
self:set_animation_speed() -- set animation speed relative to velocity
self:set_animation_speed() -- set animation speed relitive to velocity
self:check_smooth_rotation(dtime)
self:check_head_swivel(dtime)
if self.jump_sound_cooloff > 0 then self.jump_sound_cooloff = self.jump_sound_cooloff - dtime end
if self.jump_sound_cooloff > 0 then
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
end
self:do_jump()
self:set_armor_texture()
self:check_runaway_from()
self:monster_attack()
self:npc_attack()
self:check_breeding()
self:check_aggro(dtime)
if self.do_custom and self.do_custom(self, dtime) == false then return end
-- In certain circumstances, we abandon processing of certain functionality
local skip_processing = false
if update_timers(self, dtime) then
skip_processing = true
-- run custom function (defined in mob lua file)
if self.do_custom then
if self.do_custom(self, dtime) == false then
return
end
end
if update_timers(self, dtime) then return end
self:check_particlespawners(dtime)
self:check_item_pickup()
if not skip_processing then
self:check_breeding()
self:check_item_pickup()
self:set_armor_texture()
self:check_particlespawners(dtime)
if self.opinion_sound_cooloff > 0 then
self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime
end
-- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous
if math.random(1, 70) == 1 then
self:mob_sound("random", true)
end
if self:do_states(dtime) then return end
if self.opinion_sound_cooloff > 0 then
self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime
end
-- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous
if math.random(1, 70) == 1 then
self:mob_sound("random", true)
end
if mobs_debug then self:update_tag() end
if self:env_damage (dtime, pos) then return end
if self:do_states(dtime) then return end
if not self.object:get_luaentity() then
return false
end
end
local last_crash_warn_time = 0
local on_step_error_handler = function ()
local info = debug.getinfo(1, "SnlufL")
local current_time = os.time()
local time_since_warning = current_time - last_crash_warn_time
--minetest.log("previous_crash_time: " .. current_time)
--minetest.log("last_crash_time: " .. last_crash_warn_time)
--minetest.log("time_since_warning: " .. time_since_warning)
if time_since_warning > CRASH_WARN_FREQUENCY then
last_crash_warn_time = current_time
minetest.log("A game crashing bug was prevented. Please provide debug.log information to MineClone2 dev team for investigation. (Search for: --- Bug report start)")
end
minetest.log("action", "--- Bug report start (please provide a few lines before this also for context) ---")
minetest.log("action", "Stack trace: ".. tostring(debug.traceback()))
minetest.log("action", "Bug info: ".. dump(info))
minetest.log("action", "--- Bug report end ---")
end
-- main mob function
function mob_class:on_step(dtime)
local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime)
if status then
return retVal
end
end
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime

View File

@ -1,9 +1,9 @@
local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
local mob_class = mcl_mobs.mob_class
local HORNY_TIME = 30
local HORNY_AGAIN_TIME = 30 -- was 300 or 15*20
local CHILD_GROW_TIME = 60
local HORNY_TIME = 30*20
local HORNY_AGAIN_TIME = 30*20 -- was 300 or 15*20
local CHILD_GROW_TIME = 60*20
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)

View File

@ -1,4 +1,4 @@
local math, tonumber, vector, minetest, mcl_mobs = math, tonumber, vector, minetest, mcl_mobs
local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
local mob_class = mcl_mobs.mob_class
local active_particlespawners = {}
local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
@ -8,15 +8,6 @@ local player_transfer_distance = tonumber(minetest.settings:get("player_transfer
if player_transfer_distance == 0 then player_transfer_distance = math.huge end
local function validate_vector (vect)
if vect then
if tonumber(vect.x) and tonumber(vect.y) and tonumber(vect.z) then
return true
end
end
return false
end
-- custom particle effects
function mcl_mobs.effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down)
@ -394,8 +385,6 @@ function mob_class:check_head_swivel(dtime)
mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horrizonatal_head_height), final_rotation)
end
function mob_class:set_animation_speed()
local v = self.object:get_velocity()
if v then
@ -411,7 +400,7 @@ function mob_class:set_animation_speed()
end
end
--set_speed
if validate_vector(self.acc) then
if self.acc then
self.object:add_velocity(self.acc)
end
end

View File

@ -260,6 +260,8 @@ function mcl_mobs.register_mob(name, def)
-- MCL2 extensions
shooter_avoid_enemy = def.shooter_avoid_enemy,
strafes = def.strafes,
light_min = def.light_min,
light_max = def.light_max,
avoid_distance = def.avoid_distance or 9,
do_teleport = def.do_teleport,
spawn_class = def.spawn_class,
@ -489,7 +491,7 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
-- am I clicking on something with existing on_rightclick function?
local under = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[under.name]
@ -504,7 +506,15 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
local name = placer:get_player_name()
local privs = minetest.get_player_privs(name)
local dim = mcl_worlds.pos_to_dimension(placer:get_pos())
local mob_light_lvl = {mcl_mobs:mob_light_lvl(itemstack:get_name(),dim)}
-- the attribute in the light_levels table for mobs is "the_end" instead of "end"
if dim == "end" then
dim = "the_end"
end
local mob_light_level = {
light_max = mcl_mobs.registered_mobs[itemstack:get_name()].light_max,
light_min = mcl_mobs.registered_mobs[itemstack:get_name()].light_min
}
if under.name == "mcl_mobspawners:spawner" then
if minetest.is_protected(pointed_thing.under, name) then
minetest.record_protection_violation(pointed_thing.under, name)
@ -514,7 +524,7 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
minetest.chat_send_player(name, S("You need the “maphack” privilege to change the mob spawner."))
return itemstack
end
mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_lvl[1], mob_light_lvl[2])
mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_level.light_min[dim], mob_light_level.light_max[dim])
if not minetest.is_creative_enabled(name) then
itemstack:take_item()
end

View File

@ -239,15 +239,9 @@ function mob_class:is_at_water_danger()
return false
end
local yaw = self.object:get_yaw()
local pos = self.object:get_pos()
if not yaw or not pos then
return
end
local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)
local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)
local pos = self.object:get_pos()
local ypos = pos.y + self.collisionbox[2] -- just above floor
local free_fall, blocker = minetest.line_of_sight(
@ -460,7 +454,7 @@ end
-- find and replace what mob is looking for (grass, wheat etc.)
function mob_class:replace_node(pos)
function mob_class:replace(pos)
if not self.replace_rate
or not self.replace_what

View File

@ -3,9 +3,6 @@ local mob_class = mcl_mobs.mob_class
local PATHFINDING_FAIL_THRESHOLD = 100 -- no. of ticks to fail before giving up. 20p/s. 5s helps them get through door
local PATHFINDING_FAIL_WAIT = 30 -- how long to wait before trying to path again
local PATHING_START_DELAY = 4 -- When doing non-prioritised pathing, how long to wait until last mob pathed
local PATHFINDING_SEARCH_DISTANCE = 50 -- How big the square is that pathfinding will look
local PATHFINDING = "gowp"
@ -110,20 +107,14 @@ local function generate_enriched_path(wp_in, door_open_pos, door_close_pos, cur_
return wp_out
end
local last_pathing_time = os.time()
function mob_class:ready_to_path(prioritised)
function mob_class:ready_to_path()
mcl_log("Check ready to path")
if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then
mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed))
return false
else
local time_since_path_start = os.time() - last_pathing_time
mcl_log("time_since_path_start: " .. tostring(time_since_path_start))
if prioritised or (time_since_path_start) > PATHING_START_DELAY then
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
return true
end
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
return true
end
end
@ -153,7 +144,7 @@ local function calculate_path_through_door (p, cur_door_pos, t)
if n.name == "air" then
mcl_log("We have air space next to door at: " .. minetest.pos_to_string(pos_closest_to_door))
prospective_wp = minetest.find_path(p, pos_closest_to_door, PATHFINDING_SEARCH_DISTANCE, 1, 4)
prospective_wp = minetest.find_path(p,pos_closest_to_door,150,1,4)
if prospective_wp then
mcl_log("Found a path to next to door".. minetest.pos_to_string(pos_closest_to_door))
@ -163,7 +154,7 @@ local function calculate_path_through_door (p, cur_door_pos, t)
if t then
mcl_log("We have t, lets go from door to target")
local wp_otherside_door_to_target = minetest.find_path(other_side_of_door, t, PATHFINDING_SEARCH_DISTANCE, 1, 4)
local wp_otherside_door_to_target = minetest.find_path(other_side_of_door,t,150,1,4)
if wp_otherside_door_to_target and #wp_otherside_door_to_target > 0 then
append_paths (prospective_wp, wp_otherside_door_to_target)
@ -199,13 +190,9 @@ local function calculate_path_through_door (p, cur_door_pos, t)
return enriched_path
end
function mob_class:gopath(target, callback_arrived, prioritised)
function mob_class:gopath(target,callback_arrived)
if self.state == PATHFINDING then mcl_log("Already pathfinding, don't set another until done.") return end
if not self:ready_to_path(prioritised) then return end
last_pathing_time = os.time()
if not self:ready_to_path() then return end
self.order = nil
@ -213,7 +200,7 @@ function mob_class:gopath(target, callback_arrived, prioritised)
local t = vector.offset(target,0,1,0)
--Check direct route
local wp = minetest.find_path(p, t, PATHFINDING_SEARCH_DISTANCE, 1, 4)
local wp = minetest.find_path(p,t,150,1,4)
if not wp then
mcl_log("### No direct path. Path through door closest to target.")
@ -423,7 +410,7 @@ function mob_class:check_gowp(dtime)
mcl_log("No current target")
end
local final_wp = minetest.find_path(p, self._target, PATHFINDING_SEARCH_DISTANCE, 1, 4)
local final_wp = minetest.find_path(p,self._target,150,1,4)
if final_wp then
mcl_log("We can get to target here.")
-- self.waypoints = final_wp

View File

@ -311,8 +311,6 @@ end
function mob_class:set_yaw(yaw, delay, dtime)
if self.noyaw then return end
if not self.object:get_yaw() or not self.object:get_pos() then return end
if self.state ~= PATHFINDING then
self._turn_to = yaw
end
@ -464,14 +462,6 @@ function mob_class:check_for_death(cause, cmi_cause)
self:mob_sound("death")
local function death_handle(self)
if cmi_cause and cmi_cause["type"] then
--minetest.log("cmi_cause: " .. tostring(cmi_cause["type"]))
end
--minetest.log("cause: " .. tostring(cause))
-- TODO other env damage shouldn't drop xp
-- "rain", "water", "drowning", "suffocation"
-- dropped cooked item if mob died in fire or lava
if cause == "lava" or cause == "fire" then
self:item_drop(true, 0)
@ -659,6 +649,7 @@ function mob_class:do_env_damage()
-- rain
if self.rain_damage > 0 then
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
self.health = self.health - self.rain_damage
if self:check_for_death("rain", {type = "environment",
@ -671,9 +662,13 @@ function mob_class:do_env_damage()
pos.y = pos.y + 1 -- for particle effect position
-- water damage
if self.water_damage > 0 and nodef.groups.water then
if self.water_damage > 0
and nodef.groups.water then
if self.water_damage ~= 0 then
self.health = self.health - self.water_damage
mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil)
if self:check_for_death("water", {type = "environment",
@ -681,10 +676,27 @@ function mob_class:do_env_damage()
return true
end
end
elseif self.lava_damage > 0 and (nodef.groups.lava) then
-- lava damage
-- magma damage
elseif self.fire_damage > 0
and (nodef2.groups.fire) then
if self.fire_damage ~= 0 then
self.health = self.health - self.fire_damage
if self:check_for_death("fire", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
end
-- lava damage
elseif self.lava_damage > 0
and (nodef.groups.lava) then
if self.lava_damage ~= 0 then
self.health = self.health - self.lava_damage
mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
mcl_burning.set_on_fire(self.object, 10)
@ -693,20 +705,15 @@ function mob_class:do_env_damage()
return true
end
end
elseif self.fire_damage > 0 and (nodef2.groups.fire) then
-- magma damage
-- fire damage
elseif self.fire_damage > 0
and (nodef.groups.fire) then
if self.fire_damage ~= 0 then
self.health = self.health - self.fire_damage
if self:check_for_death("fire", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
end
elseif self.fire_damage > 0 and (nodef.groups.fire) then
-- fire damage
if self.fire_damage ~= 0 then
self.health = self.health - self.fire_damage
mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
mcl_burning.set_on_fire(self.object, 5)
@ -715,9 +722,12 @@ function mob_class:do_env_damage()
return true
end
end
-- damage_per_second node check
elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then
-- damage_per_second node check
self.health = self.health - nodef.damage_per_second
mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png")
if self:check_for_death("dps", {type = "environment",
@ -729,7 +739,6 @@ function mob_class:do_env_damage()
-- Drowning damage
if self.breath_max ~= -1 then
local drowning = false
if self.breathes_in_water then
if minetest.get_item_group(self.standing_in, "water") == 0 then
drowning = true
@ -737,9 +746,10 @@ function mob_class:do_env_damage()
elseif nodef.drowning > 0 then
drowning = true
end
if drowning then
self.breath = math.max(0, self.breath - 1)
mcl_mobs.effect(pos, 2, "bubble.png", nil, nil, 1, nil)
if self.breath <= 0 then
local dmg
@ -790,25 +800,25 @@ function mob_class:do_env_damage()
self.suffocation_timer = 0
end
return self:check_for_death("unknown", {type = "unknown"})
return self:check_for_death("", {type = "unknown"})
end
function mob_class:env_damage (dtime, pos)
-- environmental damage timer (every 1 second)
self.env_damage_timer = self.env_damage_timer + dtime
if self.env_damage_timer > 1 then
self.env_damage_timer = 0
if (self.state == "attack" and self.env_damage_timer > 1)
or self.state ~= "attack" then
self:check_entity_cramming()
self.env_damage_timer = 0
-- check for environmental damage (water, fire, lava etc.)
if self:do_env_damage() then
return true
end
self:replace_node(pos) -- (sheep eats grass etc.)
-- node replace check (cow eats grass etc.)
self:replace(pos)
end
end

View File

@ -24,60 +24,25 @@ local vector_floor = vector.floor
local table_copy = table.copy
local table_remove = table.remove
local pairs = pairs
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_spawning", false)
local function mcl_log (message)
if LOGGING_ON then
mcl_util.mcl_log (message, "[Mobs spawn]", true)
end
end
local dbg_spawn_attempts = 0
local dbg_spawn_succ = 0
local dbg_spawn_counts = {}
-- range for mob count
local aoc_range = 136
local remove_far = true
local WAIT_FOR_SPAWN_ATTEMPT = 10
local FIND_SPAWN_POS_RETRIES = 16
local FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN = 8
local MOB_SPAWN_ZONE_INNER = 24
local MOB_SPAWN_ZONE_MIDDLE = 32
local MOB_SPAWN_ZONE_OUTER = 128
-- range for mob count
local MOB_CAP_INNER_RADIUS = 32
local aoc_range = 136
local MISSING_CAP_DEFAULT = 15
local MOBS_CAP_CLOSE = 5
local SPAWN_MAPGEN_LIMIT = mcl_vars.mapgen_limit - 150
local mob_cap = {
hostile = tonumber(minetest.settings:get("mcl_mob_cap_monster")) or 70,
passive = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 13,
monster = tonumber(minetest.settings:get("mcl_mob_cap_monster")) or 70,
animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10,
ambient = tonumber(minetest.settings:get("mcl_mob_cap_ambient")) or 15,
water = tonumber(minetest.settings:get("mcl_mob_cap_water")) or 8,
water = tonumber(minetest.settings:get("mcl_mob_cap_water")) or 5, --currently unused
water_ambient = tonumber(minetest.settings:get("mcl_mob_cap_water_ambient")) or 20, --currently unused
player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75,
total = tonumber(minetest.settings:get("mcl_mob_cap_total")) or 500,
}
local peaceful_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_peaceful_percentage_spawned")) or 35
local peaceful_group_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_peaceful_group_percentage_spawned")) or 15
local hostile_group_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_hostile_group_percentage_spawned")) or 20
mcl_log("Mob cap hostile: " .. mob_cap.hostile)
mcl_log("Mob cap water: " .. mob_cap.water)
mcl_log("Mob cap passive: " .. mob_cap.passive)
mcl_log("Percentage of peacefuls spawned: " .. peaceful_percentage_spawned)
mcl_log("Percentage of peaceful spawns are group: " .. peaceful_group_percentage_spawned)
mcl_log("Percentage of hostile spawns are group: " .. hostile_group_percentage_spawned)
--do mobs spawn?
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false
@ -285,58 +250,22 @@ local function count_mobs_total(mob_type)
return num
end
local function count_mobs_add_entry (mobs_list, mob_cat)
if mobs_list[mob_cat] then
mobs_list[mob_cat] = mobs_list[mob_cat] + 1
else
mobs_list[mob_cat] = 1
end
end
--categorise_by can be name or type or spawn_class
local function count_mobs_all(categorise_by, pos)
local mobs_found_wide = {}
local mobs_found_close = {}
local function count_mobs_all()
local mobs_found = {}
local num = 0
for _,entity in pairs(minetest.luaentities) do
if entity and entity.is_mob then
local add_entry = false
--local mob_type = entity.type -- animal / monster / npc
local mob_cat = entity[categorise_by]
if pos then
local mob_pos = entity.object:get_pos()
if mob_pos then
local distance = vector.distance(pos, mob_pos)
--mcl_log("distance: ".. distance)
if distance <= MOB_SPAWN_ZONE_MIDDLE then
--mcl_log("distance is close")
count_mobs_add_entry (mobs_found_close, mob_cat)
count_mobs_add_entry (mobs_found_wide, mob_cat)
add_entry = true
elseif distance <= MOB_SPAWN_ZONE_OUTER then
--mcl_log("distance is wide")
count_mobs_add_entry (mobs_found_wide, mob_cat)
add_entry = true
else
--mcl_log("mob_pos: " .. minetest.pos_to_string(mob_pos))
end
end
if entity.is_mob then
local mob_type = entity.type -- animal / monster / npc
local mob_name = entity.name
if mobs_found[mob_name] then
mobs_found[mob_name] = mobs_found[mob_name] + 1
else
count_mobs_add_entry (mobs_found_wide, mob_cat)
add_entry = true
end
if add_entry then
num = num + 1
mobs_found[mob_name] = 1
end
num = num + 1
end
end
--mcl_log("num: ".. num)
return mobs_found_close, mobs_found_wide, num
return mobs_found, num
end
local function count_mobs_total_cap(mob_type)
@ -351,32 +280,6 @@ local function count_mobs_total_cap(mob_type)
return num
end
local function output_mob_stats(mob_counts, total_mobs, chat_display)
if (total_mobs) then
local total_output = "Total mobs found: " .. total_mobs
if chat_display then
minetest.log(total_output)
else
minetest.log("action", total_output)
end
end
local detailed = ""
if mob_counts then
for k, v1 in pairs(mob_counts) do
detailed = detailed .. tostring(k) .. ": " .. tostring(v1) .. "; "
end
end
if detailed and detailed ~= "" then
if chat_display then
minetest.log(detailed)
else
minetest.log("action", detailed)
end
end
end
-- global functions
function mcl_mobs:spawn_abm_check(pos, node, name)
@ -413,8 +316,6 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
--this is where all of the spawning information is kept
local spawn_dictionary = {}
--this is where all of the spawning information is kept for mobs that don't naturally spawn
local non_spawn_dictionary = {}
local summary_chance = 0
function mcl_mobs:spawn_setup(def)
@ -480,47 +381,6 @@ function mcl_mobs:spawn_setup(def)
summary_chance = summary_chance + chance
end
function mcl_mobs:mob_light_lvl(mob_name, dimension)
local spawn_dictionary_consolidated = {}
--see if the mob exists in the nonspawn dictionary, if so then return light values
if non_spawn_dictionary[mob_name] ~= nil then
local mob_dimension = non_spawn_dictionary[mob_name][dimension]
if mob_name ~= nil then
return mob_dimension.min_light,mob_dimension.max_light
else
return non_spawn_dictionary[mob_name]["overworld"].min_light, non_spawn_dictionary[mob_name]["overworld"].max_light
end
--if the mob doesn't exist in non_spawn, check spawn_dictonary
else
for i,v in pairs(spawn_dictionary) do
if spawn_dictionary[spawn_dictionary[i].name] == nil then
spawn_dictionary_consolidated[spawn_dictionary[i].name] = {}
end
spawn_dictionary_consolidated[spawn_dictionary[i].name][dimension] = {
["min_light"] = spawn_dictionary[i].min_light,
["max_light"] = spawn_dictionary[i].max_light
}
end
mob_dimension = spawn_dictionary_consolidated[mob_name][dimension]
mob_dimension_default = spawn_dictionary_consolidated[mob_name]["overworld"]
if spawn_dictionary_consolidated[mob_name] == mob_name and mob_dimension ~= nil then
return mob_dimension.min_light, mob_dimension.max_light
else
return mob_dimension_default.min_light, mob_dimension_default.max_light
end
end
end
function mcl_mobs:non_spawn_specific(mob_name,dimension,min_light,max_light)
table.insert(non_spawn_dictionary, mob_name)
non_spawn_dictionary[mob_name] = {
[dimension] = {
min_light = min_light , max_light = max_light
}
}
end
function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
-- Do mobs spawn at all?
@ -562,23 +422,18 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
summary_chance = summary_chance + chance
end
local two_pi = 2 * math.pi
local function get_next_mob_spawn_pos(pos)
-- TODO We should consider spawning something a little further away sporadically.
-- It would be good for sky farms and variance, rather than all being on the 24 - 32 block away radius
local distance = math_random(MOB_SPAWN_ZONE_INNER, MOB_SPAWN_ZONE_MIDDLE)
local distance = math_random(25, 32)
local angle = math_random() * two_pi
-- TODO Floor xoff and zoff and add 0.5 so it tries to spawn in the middle of the square. Less failed attempts.
local xoff = math_round(distance * math_cos(angle))
local zoff = math_round(distance * math_sin(angle))
return vector.offset(pos, xoff, 0, zoff)
local yoff = math_round(distance * math_sin(angle))
return vector.offset(pos, xoff, 0, yoff)
end
local function decypher_limits(posy)
posy = math_floor(posy)
return posy - MOB_SPAWN_ZONE_MIDDLE, posy + MOB_SPAWN_ZONE_MIDDLE
return posy - 32, posy + 32
end
--a simple helper function for mob_spawn
@ -629,9 +484,7 @@ local function has_room(self,pos)
return true
end
local function spawn_check(pos, spawn_def)
local function spawn_check(pos,spawn_def,ignore_caps)
if not spawn_def then return end
dbg_spawn_attempts = dbg_spawn_attempts + 1
local dimension = mcl_worlds.pos_to_dimension(pos)
@ -654,8 +507,17 @@ local function spawn_check(pos, spawn_def)
local is_leaf = get_item_group(gotten_node, "leaves") ~= 0
local is_bedrock = gotten_node == "mcl_core:bedrock"
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
local mob_count_wide = 0
local mob_count = 0
if not ignore_caps then
mob_count = count_mobs(pos,32,mob_type)
mob_count_wide = count_mobs(pos,aoc_range,mob_type)
end
if pos and spawn_def
and ( mob_count_wide < (mob_cap[mob_type] or 15) )
and ( mob_count < 5 )
and pos.y >= spawn_def.min_height
and pos.y <= spawn_def.max_height
and spawn_def.dimension == dimension
@ -670,8 +532,12 @@ local function spawn_check(pos, spawn_def)
and not is_bedrock then
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(pos)
if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then
return true
--gotten_light is a table sometimes, causing a crash. Don't know the cause.
if type(gotten_light) ~= "table" then
if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then
return true
end
end
end
return false
@ -691,7 +557,8 @@ function mcl_mobs.spawn(pos,id)
end
local function spawn_group(p,mob,spawn_on,amount_to_spawn)
local function spawn_group(p,mob,spawn_on,group_max,group_min)
if not group_min then group_min = 1 end
local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on)
local o
table.shuffle(nn)
@ -699,10 +566,9 @@ local function spawn_group(p,mob,spawn_on,amount_to_spawn)
nn = {}
table.insert(nn,p)
end
for i = 1, amount_to_spawn do
for i = 1, math.random(group_min,group_max) do
local sp = vector.offset(nn[math.random(#nn)],0,1,0)
if spawn_check(nn[math.random(#nn)],mob) then
if spawn_check(nn[math.random(#nn)],mob,true) then
if mob.type_of_spawning == "water" then
sp = get_water_spawn(sp)
end
@ -793,113 +659,25 @@ if mobs_spawn then
-- Get pos to spawn, x and z are randomised, y is range
local function mob_cap_space (pos, mob_type, mob_counts_close, mob_counts_wide)
-- Some mob examples
--type = "monster", spawn_class = "hostile",
--type = "animal", spawn_class = "passive",
--local cod = { type = "animal", spawn_class = "water",
local type_cap = mob_cap[mob_type] or MISSING_CAP_DEFAULT
local close_zone_cap = MOBS_CAP_CLOSE
local mob_total_wide = mob_counts_wide[mob_type]
if not mob_total_wide then
--mcl_log("none of type found. set as 0")
mob_total_wide = 0
end
local cap_space_wide = type_cap - mob_total_wide
if cap_space_wide < 1 then
cap_space_wide = 0
end
local mob_total_close = mob_counts_close[mob_type]
if not mob_total_close then
--mcl_log("none of type found. set as 0")
mob_total_close = 0
end
local cap_space_close = close_zone_cap - mob_total_close
if cap_space_close < 1 then
cap_space_close = 0
end
--mcl_log("spawn_class: " .. spawn_class)
if false and mob_type == "water" then
mcl_log("mob_type: " .. mob_type .. " and pos: " .. minetest.pos_to_string(pos))
mcl_log("wide: " .. mob_total_wide .. "/" .. type_cap)
mcl_log("cap_space_wide: " .. cap_space_wide)
mcl_log("close: " .. mob_total_close .. "/" .. close_zone_cap)
mcl_log("cap_space_close: " .. cap_space_close)
end
return cap_space_wide, cap_space_close
end
local function find_spawning_position(pos, max_times)
local spawning_position
local max_loops = 1
if max_times then max_loops = max_times end
local y_min, y_max = decypher_limits(pos.y)
mcl_log("mapgen_limit: " .. SPAWN_MAPGEN_LIMIT)
local i = 0
repeat
local goal_pos = get_next_mob_spawn_pos(pos)
if math.abs(goal_pos.x) <= SPAWN_MAPGEN_LIMIT and math.abs(pos.y) <= SPAWN_MAPGEN_LIMIT and math.abs(goal_pos.z) <= SPAWN_MAPGEN_LIMIT then
local spawning_position_list = find_nodes_in_area_under_air(
{x = goal_pos.x, y = y_min, z = goal_pos.z},
{x = goal_pos.x, y = y_max, z = goal_pos.z},
{"group:solid", "group:water", "group:lava"}
)
if #spawning_position_list > 0 then
mcl_log("Spawning positions available: " .. minetest.pos_to_string(goal_pos))
spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
else
mcl_log("Spawning position isn't good. Do not spawn: " .. minetest.pos_to_string(goal_pos))
end
else
mcl_log("Pos outside mapgen limits: " .. minetest.pos_to_string(goal_pos))
end
i = i + 1
if i >= max_loops then
mcl_log("Cancel finding spawn positions at: " .. max_loops)
break
end
until spawning_position
return spawning_position
end
local function spawn_a_mob(pos)
--create a disconnected clone of the spawn dictionary, prevents memory leak
local function spawn_a_mob(pos, dimension, y_min, y_max)
--create a disconnected clone of the spawn dictionary
--prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary)
local spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES)
if not spawning_position then
minetest.log("action", "[Mobs spawn] Cannot find a valid spawn position after retries: " .. FIND_SPAWN_POS_RETRIES)
return
end
local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("spawn_class", spawning_position)
--output_mob_stats(mob_counts_close, total_mobs)
--output_mob_stats(mob_counts_wide)
local goal_pos = get_next_mob_spawn_pos(pos)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
local spawning_position_list = find_nodes_in_area_under_air(
{x = goal_pos.x, y = y_min, z = goal_pos.z},
{x = goal_pos.x, y = y_max, z = goal_pos.z},
{"group:solid", "group:water", "group:lava"}
)
if #spawning_position_list <= 0 then return end
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
local noise = perlin_noise:get_3d(spawning_position)
local current_summary_chance = summary_chance
table.shuffle(mob_library_worker_table)
while #mob_library_worker_table > 0 do
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
local mob_index = 1
@ -910,95 +688,39 @@ if mobs_spawn then
mob_chance = mob_library_worker_table[mob_index].chance
step_chance = step_chance + mob_chance
end
--minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance)
local mob_def = mob_library_worker_table[mob_index]
--minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance)
if mob_def and mob_def.name and minetest.registered_entities[mob_def.name] then
local mob_def_ent = minetest.registered_entities[mob_def.name]
--local mob_type = mob_def_ent.type
local mob_spawn_class = mob_def_ent.spawn_class
--mcl_log("mob_spawn_class: " .. mob_spawn_class)
local cap_space_wide, cap_space_close = mob_cap_space (spawning_position, mob_spawn_class, mob_counts_close, mob_counts_wide)
if cap_space_close > 0 and cap_space_wide > 0 then
--mcl_log("Cap space available")
-- Spawn caps for animals and water creatures fill up rapidly. Need to throttle this somewhat
-- for performance and for early game challenge. We don't want to reduce hostiles though.
local spawn_hostile = (mob_spawn_class == "hostile")
local spawn_passive = (mob_spawn_class ~= "hostile") and math.random(100) < peaceful_percentage_spawned
-- or not hostile
--mcl_log("Spawn_passive: " .. tostring(spawn_passive))
--mcl_log("Spawn_hostile: " .. tostring(spawn_hostile))
if (spawn_hostile or spawn_passive) and spawn_check(spawning_position,mob_def) then
if mob_def.type_of_spawning == "water" then
spawning_position = get_water_spawn(spawning_position)
if not spawning_position then
minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos)))
return
end
end
if mob_def_ent.can_spawn and not mob_def_ent.can_spawn(spawning_position) then
minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position)))
local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4
local spawn_in_group_min = minetest.registered_entities[mob_def.name].spawn_in_group_min or 1
local mob_type = minetest.registered_entities[mob_def.name].type
if spawn_check(spawning_position,mob_def) then
if mob_def.type_of_spawning == "water" then
spawning_position = get_water_spawn(spawning_position)
if not spawning_position then
minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos)))
return
end
--everything is correct, spawn mob
local spawn_in_group = mob_def_ent.spawn_in_group or 4
local spawn_group_hostile = (mob_spawn_class == "hostile") and (math.random(100) < hostile_group_percentage_spawned)
local spawn_group_passive = (mob_spawn_class ~= "hostile") and (math.random(100) < peaceful_group_percentage_spawned)
mcl_log("spawn_group_hostile: " .. tostring(spawn_group_hostile))
mcl_log("spawn_group_passive: " .. tostring(spawn_group_passive))
local spawned
if spawn_in_group and (spawn_group_hostile or spawn_group_passive) then
local group_min = mob_def_ent.spawn_in_group_min or 1
if not group_min then group_min = 1 end
local amount_to_spawn = math.random(group_min,spawn_in_group)
if amount_to_spawn > cap_space_wide then
mcl_log("Spawning quantity: " .. amount_to_spawn)
mcl_log("Throttle amount to cap space: " .. cap_space_wide)
amount_to_spawn = cap_space_wide
end
if logging then
minetest.log("action", "[mcl_mobs] A group of " ..amount_to_spawn .. " " .. mob_def.name .. " mob spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at " .. minetest.pos_to_string(spawning_position, 1))
end
spawned = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name}, amount_to_spawn)
else
if logging then
minetest.log("action", "[mcl_mobs] Mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at ".. minetest.pos_to_string(spawning_position, 1))
end
spawned = mcl_mobs.spawn(spawning_position, mob_def.name)
end
if spawned then
--mcl_log("We have spawned")
mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("type", pos)
local new_spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN)
if new_spawning_position then
mcl_log("Setting new spawning position")
spawning_position = new_spawning_position
else
mcl_log("Cannot set new spawning position")
end
end
else
mcl_log("Spawn check failed")
end
else
mcl_log("Cap space full")
end
if minetest.registered_entities[mob_def.name].can_spawn and not minetest.registered_entities[mob_def.name].can_spawn(spawning_position) then
minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position)))
return
end
--everything is correct, spawn mob
local object
if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then
if logging then
minetest.log("action", "[mcl_mobs] A group of mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at " .. minetest.pos_to_string(spawning_position, 1))
end
object = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name},spawn_in_group,spawn_in_group_min)
else
if logging then
minetest.log("action", "[mcl_mobs] Mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at ".. minetest.pos_to_string(spawning_position, 1))
end
object = mcl_mobs.spawn(spawning_position, mob_def.name)
end
end
end
current_summary_chance = current_summary_chance - mob_chance
table_remove(mob_library_worker_table, mob_index)
@ -1010,24 +732,22 @@ if mobs_spawn then
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < WAIT_FOR_SPAWN_ATTEMPT then return end
if timer < 10 then return end
timer = 0
local players = get_connected_players()
local total_mobs = count_mobs_total_cap()
if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then
minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.")
return
end --mob cap per player
for _, player in pairs(players) do
local pos = player:get_pos()
local dimension = mcl_worlds.pos_to_dimension(pos)
-- ignore void and unloaded area
if dimension ~= "void" and dimension ~= "default" then
spawn_a_mob(pos)
local y_min, y_max = decypher_limits(pos.y)
spawn_a_mob(pos, dimension, y_min, y_max)
end
end
end)
@ -1059,16 +779,27 @@ function mob_class:check_despawn(pos, dtime)
end
end
minetest.register_chatcommand("mobstats",{
privs = { debug = true },
func = function(n,param)
--minetest.chat_send_player(n,dump(dbg_spawn_counts))
minetest.chat_send_player(n,dump(dbg_spawn_counts))
local pos = minetest.get_player_by_name(n):get_pos()
minetest.chat_send_player(n,"mobs: within 32 radius of player/total loaded :"..count_mobs(pos,MOB_CAP_INNER_RADIUS) .. "/" .. count_mobs_total())
minetest.chat_send_player(n,"spawning attempts since server start:" .. dbg_spawn_succ .. "/" .. dbg_spawn_attempts)
minetest.chat_send_player(n,"mobs within 32 radius of player:"..count_mobs(pos,32))
minetest.chat_send_player(n,"total mobs:"..count_mobs_total())
minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts)
minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ)
local mob_counts, total_mobs = count_mobs_all()
if (total_mobs) then
minetest.log("action", "Total mobs found: " .. total_mobs)
end
if mob_counts then
for k, v1 in pairs(mob_counts) do
minetest.log("action", "k: " .. tostring(k))
minetest.log("action", "v1: " .. tostring(v1))
end
end
local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("name") -- Can use "type"
output_mob_stats(mob_counts_wide, total_mobs, true)
end
})

View File

@ -9,7 +9,16 @@ local axolotl = {
hp_max = 14,
xp_min = 1,
xp_max = 7,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
head_swivel = "head.control",
bone_eye_height = -1,
head_eye_height = -0.5,
@ -169,8 +178,8 @@ mcl_mobs:spawn_specific(
"JungleEdgeM_underground",
"LushCaves",
},
0,
minetest.LIGHT_MAX+1,
axolotl.light_min.overworld,
axolotl.light_max.overworld,
30,
4000,
3,

View File

@ -2,7 +2,19 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:bat", {
-- Spawning
--[[ If the game has been launched between the 20th of October and the 3rd of November system time,
-- the maximum spawn light level is increased. ]]
local date = os.date("*t")
local maxlight
if (date.month == 10 and date.day >= 20) or (date.month == 11 and date.day <= 3) then
maxlight = 6
else
maxlight = 3
end
local bat = {
description = S("Bat"),
type = "animal",
spawn_class = "ambient",
@ -11,6 +23,17 @@ mcl_mobs.register_mob("mobs_mc:bat", {
passive = true,
hp_min = 6,
hp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = maxlight,
nether = maxlight,
the_end = maxlight
},
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
visual = "mesh",
mesh = "mobs_mc_bat.b3d",
@ -50,20 +73,8 @@ mcl_mobs.register_mob("mobs_mc:bat", {
jump = false,
fly = true,
makes_footstep_sound = false,
})
-- Spawning
--[[ If the game has been launched between the 20th of October and the 3rd of November system time,
-- the maximum spawn light level is increased. ]]
local date = os.date("*t")
local maxlight
if (date.month == 10 and date.day >= 20) or (date.month == 11 and date.day <= 3) then
maxlight = 6
else
maxlight = 3
end
}
mcl_mobs.register_mob("mobs_mc:bat", bat)
-- Spawn on solid blocks at or below Sea level and the selected light level
mcl_mobs:spawn_specific(
@ -134,8 +145,8 @@ mcl_mobs:spawn_specific(
"JungleEdge",
"SavannaM",
},
0,
maxlight,
bat.light_min.overworld,
bat.light_max.overworld,
20,
5000,
2,

View File

@ -11,8 +11,7 @@ local mod_target = minetest.get_modpath("mcl_target")
--################### BLAZE
--###################
mcl_mobs.register_mob("mobs_mc:blaze", {
local blaze = {
description = S("Blaze"),
type = "monster",
spawn_class = "hostile",
@ -22,6 +21,16 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
hp_max = 20,
xp_min = 10,
xp_max = 10,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 11,
nether = 11,
the_end = 11
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
rotate = -180,
visual = "mesh",
@ -58,8 +67,8 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
animation = {
stand_speed = 25,
stand_start = 0,
stand_end = 100,
walk_speed = 25,
stand_end = 100,
walk_speed = 25,
walk_start = 0,
walk_end = 100,
run_speed = 50,
@ -137,15 +146,16 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
},
})
end,
})
}
mcl_mobs.register_mob("mobs_mc:blaze", blaze)
mcl_mobs:spawn_specific(
"mobs_mc:blaze",
"nether",
"ground",
{"Nether"},
0,
minetest.LIGHT_MAX+1,
blaze.light_min.nether,
blaze.light_max.nether,
30,
5000,
3,
@ -207,6 +217,5 @@ mcl_mobs.register_arrow("mobs_mc:blaze_fireball", {
end
})
mcl_mobs:non_spawn_specific("mobs_mc:blaze", "overworld", 0, 11)
-- spawn eggs.
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:blaze", S("Blaze"), "#f6b201", "#fff87e", 0)

View File

@ -6,9 +6,7 @@ local S = minetest.get_translator("mobs_mc")
--################### CHICKEN
--###################
mcl_mobs.register_mob("mobs_mc:chicken", {
local chicken = {
description = S("Chicken"),
type = "animal",
spawn_class = "passive",
@ -18,6 +16,16 @@ mcl_mobs.register_mob("mobs_mc:chicken", {
hp_max = 4,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 9,
nether = 9,
the_end = 9
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
floats = 1,
head_swivel = "head.control",
@ -111,8 +119,9 @@ mcl_mobs.register_mob("mobs_mc:chicken", {
max_hear_distance = 16,
}, true)
end,
}
})
mcl_mobs.register_mob("mobs_mc:chicken", chicken)
--spawn
mcl_mobs:spawn_specific(
@ -155,8 +164,8 @@ mcl_mobs:spawn_specific(
"Swampland",
"Swampland_shore"
},
9,
minetest.LIGHT_MAX+1,
chicken.light_min.overworld,
chicken.light_max.overworld,
30, 17000,
3,
mobs_mc.water_level,

View File

@ -38,16 +38,26 @@ local cod = {
hp_max = 3,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
armor = 100,
rotate = 180,
spawn_in_group_min = 2, -- was 3
spawn_in_group = 4, -- was 8 nerfed until we can cap them properly locally. this is a group size, not a per spawn attempt
spawn_in_group_min = 3,
spawn_in_group = 8,
tilt_swim = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3},
visual = "mesh",
mesh = "extra_mobs_cod.b3d",
textures = {
{"mobs_mc_cod.png"}
{"extra_mobs_cod.png"}
},
sounds = {
},
@ -263,8 +273,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
cod.light_min.overworld,
cod.light_max.overworld,
30,
4000,
3,

View File

@ -12,9 +12,19 @@ local cow_def = {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 9,
nether = 9,
the_end = 9
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
spawn_in_group = 4,
spawn_in_group_min = 2,
spawn_in_group_min = 3,
visual = "mesh",
mesh = "mobs_mc_cow.b3d",
textures = { {
@ -93,8 +103,8 @@ mcl_mobs.register_mob("mobs_mc:cow", cow_def)
-- Mooshroom
local mooshroom_def = table.copy(cow_def)
mooshroom_def.description = S("Mooshroom")
mooshroom_def.spawn_in_group_min = 2
mooshroom_def.spawn_in_group = 4
mooshroom_def.spawn_in_group_min = 4
mooshroom_def.spawn_in_group = 8
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
mooshroom_def.on_rightclick = function(self, clicker)
if self:feed_tame(clicker, 1, true, false) then return end
@ -204,8 +214,8 @@ mcl_mobs:spawn_specific(
"Swampland",
"Swampland_shore"
},
9,
minetest.LIGHT_MAX+1,
cow_def.light_min.overworld,
cow_def.light_max.overworld,
30,
17000,
10,
@ -222,8 +232,8 @@ mcl_mobs:spawn_specific(
"MushroomIslandShore",
"MushroomIsland"
},
9,
minetest.LIGHT_MAX+1,
cow_def.light_min,
cow_def.light_max,
30,
17000,
5,

View File

@ -7,9 +7,7 @@ local S = minetest.get_translator("mobs_mc")
--###################
mcl_mobs.register_mob("mobs_mc:creeper", {
local creeper = {
type = "monster",
spawn_class = "hostile",
spawn_in_group = 1,
@ -17,6 +15,16 @@ mcl_mobs.register_mob("mobs_mc:creeper", {
hp_max = 20,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
pathfinding = 1,
visual = "mesh",
@ -131,9 +139,11 @@ mcl_mobs.register_mob("mobs_mc:creeper", {
floats = 1,
fear_height = 4,
view_range = 16,
})
}
mcl_mobs.register_mob("mobs_mc:creeper_charged", {
mcl_mobs.register_mob("mobs_mc:creeper", creeper)
local creeper_charged = {
description = S("Creeper"),
type = "monster",
spawn_class = "hostile",
@ -260,7 +270,8 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", {
--Having trouble when fire is placed with lightning
fire_resistant = true,
glow = 3,
})
}
mcl_mobs.register_mob("mobs_mc:creeper_charged", creeper_charged)
mcl_mobs:spawn_specific(
"mobs_mc:creeper",
@ -402,8 +413,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
creeper.light_min.overworld,
creeper.light_max.overworld,
20,
16500,
2,

View File

@ -38,12 +38,22 @@ local dolphin = {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
armor = 100,
walk_chance = 100,
breath_max = 120,
rotate = 180,
spawn_in_group_min = 2, -- was 3
spawn_in_group = 4, -- was 4. nerfed until water has own cap, and it represents max pack size rather than per spawn attempt
spawn_in_group_min = 3,
spawn_in_group = 5,
tilt_swim = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3},
visual = "mesh",
@ -241,8 +251,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
dolphin.light_min.overworld,
dolphin.light_max.overworld,
30,
4000,
3,

View File

@ -48,7 +48,7 @@ local function check_pos(self)
end
end
mcl_mobs.register_mob("mobs_mc:enderdragon", {
local enderdragon = {
description = S("Ender Dragon"),
type = "monster",
spawn_class = "hostile",
@ -59,6 +59,16 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", {
hp_min = 200,
xp_min = 500,
xp_max = 500,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-2, 3, -2, 2, 5, 2},
physical = false,
visual = "mesh",
@ -136,7 +146,8 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", {
end
end,
fire_resistant = true,
})
}
mcl_mobs.register_mob("mobs_mc:enderdragon", enderdragon)
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
@ -174,4 +185,3 @@ mcl_mobs.register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "#252525", "#b31
mcl_wip.register_wip_item("mobs_mc:enderdragon")
mcl_mobs:non_spawn_specific("mobs_mc:enderdragon","overworld",0,minetest.LIGHT_MAX+1)

View File

@ -255,7 +255,7 @@ local psdefs = {{
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
}}
mcl_mobs.register_mob("mobs_mc:enderman", {
local enderman = {
description = S("Enderman"),
type = "monster",
spawn_class = "passive",
@ -266,6 +266,16 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
hp_max = 40,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 11,
the_end = minetest.LIGHT_MAX+1,
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3},
visual = "mesh",
mesh = "mobs_mc_enderman.b3d",
@ -631,7 +641,8 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
view_range = 64,
fear_height = 4,
attack_type = "dogfight",
})
}
mcl_mobs.register_mob("mobs_mc:enderman", enderman)
-- End spawn
mcl_mobs:spawn_specific(
@ -646,8 +657,8 @@ mcl_mobs:spawn_specific(
"EndBorder",
"EndSmallIslands"
},
0,
minetest.LIGHT_MAX+1,
enderman.light_min.the_end,
enderman.light_max.the_end,
30,
3000,
12,
@ -794,8 +805,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
enderman.light_min.overworld,
enderman.light_max.overworld,
30,
19000,
2,
@ -811,8 +822,8 @@ mcl_mobs:spawn_specific(
"Nether",
"SoulsandValley",
},
0,
11,
enderman.light_min.nether,
enderman.light_max.nether,
30,
27500,
4,
@ -827,8 +838,8 @@ mcl_mobs:spawn_specific(
{
"WarpedForest"
},
0,
11,
enderman.light_min.nether,
enderman.light_max.nether,
30,
5000,
4,

View File

@ -3,8 +3,7 @@
--###################
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:endermite", {
local endermite = {
description = S("Endermite"),
type = "monster",
spawn_class = "hostile",
@ -13,6 +12,16 @@ mcl_mobs.register_mob("mobs_mc:endermite", {
hp_max = 8,
xp_min = 3,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7
},
armor = {fleshy = 100, arthropod = 100},
group_attack = true,
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.29, 0.2},
@ -36,7 +45,8 @@ mcl_mobs.register_mob("mobs_mc:endermite", {
view_range = 16,
damage = 2,
reach = 1,
})
}
mcl_mobs.register_mob("mobs_mc:endermite", endermite)
mcl_mobs.register_egg("mobs_mc:endermite", S("Endermite"), "#161616", "#6d6d6d", 0)
mcl_mobs:non_spawn_specific("mobs_mc:endermite","overworld",0,7)

View File

@ -9,8 +9,7 @@ local S = minetest.get_translator("mobs_mc")
--################### GHAST
--###################
mcl_mobs.register_mob("mobs_mc:ghast", {
local ghast = {
description = S("Ghast"),
type = "monster",
spawn_class = "hostile",
@ -20,6 +19,16 @@ mcl_mobs.register_mob("mobs_mc:ghast", {
hp_max = 10,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7
},
collisionbox = {-2, 5, -2, 2, 9, 2},
visual = "mesh",
mesh = "mobs_mc_ghast.b3d",
@ -82,7 +91,8 @@ mcl_mobs.register_mob("mobs_mc:ghast", {
self.object:set_properties({textures=self.base_texture})
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:ghast", ghast)
mcl_mobs:spawn_specific(
@ -94,8 +104,8 @@ mcl_mobs:spawn_specific(
"SoulsandValley",
"BasaltDelta",
},
0,
7,
ghast.light_min.nether,
ghast.light_max.nether,
30,
72000,
2,
@ -139,6 +149,6 @@ mcl_mobs.register_arrow("mobs_mc:fireball", {
mcl_mobs:non_spawn_specific("mobs_mc:ghast","overworld","0","7")
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:ghast", S("Ghast"), "#f9f9f9", "#bcbcbc", 0)

View File

@ -25,11 +25,11 @@ local base_psdef = {
local psdefs = {}
for i=1,4 do
local p = table.copy(base_psdef)
p.texture = "mobs_mc_glow_squid_glint"..i..".png"
p.texture = "extra_mobs_glow_squid_glint"..i..".png"
table.insert(psdefs,p)
end
mcl_mobs.register_mob("mobs_mc:glow_squid", {
local glow_squid = {
type = "animal",
spawn_class = "water",
can_despawn = true,
@ -38,6 +38,16 @@ mcl_mobs.register_mob("mobs_mc:glow_squid", {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX + 1,
nether = minetest.LIGHT_MAX + 1,
the_end = minetest.LIGHT_MAX + 1
},
armor = 100,
rotate = 0,
-- tilt_swim breaks the animations.
@ -47,7 +57,7 @@ mcl_mobs.register_mob("mobs_mc:glow_squid", {
visual = "mesh",
mesh = "extra_mobs_glow_squid.b3d",
textures = {
{ "mobs_mc_glow_squid.png" }
{ "extra_mobs_glow_squid.png" }
},
sounds = {
damage = { name = "mobs_mc_squid_hurt", gain = 0.3 },
@ -84,7 +94,8 @@ mcl_mobs.register_mob("mobs_mc:glow_squid", {
glow = minetest.LIGHT_MAX,
particlespawners = psdefs,
})
}
mcl_mobs.register_mob("mobs_mc:glow_squid", glow_squid)
-- spawning
local water = mobs_mc.water_level - 1
@ -234,8 +245,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX + 1,
glow_squid.light_min.overworld,
glow_squid.light_max.overworld,
30,
10000,
3,

View File

@ -3,8 +3,7 @@
--###################
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:guardian", {
local guardian = {
description = S("Guardian"),
type = "monster",
spawn_class = "hostile",
@ -14,6 +13,16 @@ mcl_mobs.register_mob("mobs_mc:guardian", {
hp_max = 30,
xp_min = 10,
xp_max = 10,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = minetest.LIGHT_MAX+1,
the_end = 7,
},
breath_max = -1,
passive = false,
attack_type = "dogfight",
@ -97,7 +106,8 @@ mcl_mobs.register_mob("mobs_mc:guardian", {
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
jump = false,
view_range = 16,
})
}
mcl_mobs.register_mob("mobs_mc:guardian", guardian)
-- Spawning disabled due to size issues
-- TODO: Re-enable spawning

View File

@ -6,7 +6,7 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:guardian_elder", {
local guardian_elder = {
description = S("Elder Guardian"),
type = "monster",
spawn_class = "hostile",
@ -14,6 +14,16 @@ mcl_mobs.register_mob("mobs_mc:guardian_elder", {
hp_max = 80,
xp_min = 10,
xp_max = 10,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = minetest.LIGHT_MAX+1,
the_end = 7,
},
breath_max = -1,
passive = false,
attack_type = "dogfight",
@ -105,7 +115,8 @@ mcl_mobs.register_mob("mobs_mc:guardian_elder", {
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
jump = false,
view_range = 16,
})
}
mcl_mobs.register_mob("mobs_mc:guardian_elder", guardian_elder)
-- Spawning disabled due to size issues <- what do you mean? -j4i
-- TODO: Re-enable spawning

View File

@ -17,6 +17,16 @@ local hoglin = {
hp_max = 40,
xp_min = 9,
xp_max = 9,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
armor = {fleshy = 90},
attack_type = "dogfight",
damage = 4,
@ -123,15 +133,13 @@ mcl_mobs:spawn_specific(
"Nether",
"CrimsonForest"
},
0,
minetest.LIGHT_MAX+1,
hoglin.light_min.nether,
hoglin.light_max.nether,
30,
6000,
3,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
mcl_mobs:non_spawn_specific("mobs_mc:hoglin","overworld",0,7)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:hoglin", S("Hoglin"), "#85682e", "#2b2140", 0)

View File

@ -125,7 +125,7 @@ local horse = {
type = "animal",
spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 4, -- was 6. nerfed until group size is a cap rather than per spawn cycle
spawn_in_group = 6,
visual = "mesh",
mesh = "mobs_mc_horse.b3d",
visual_size = {x=3.0, y=3.0},
@ -167,6 +167,16 @@ local horse = {
hp_max = 30,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
floats = 1,
makes_footstep_sound = true,
jump = true,
@ -609,8 +619,8 @@ mcl_mobs:spawn_specific(
"Savanna_beach",
"Plains_beach",
},
0,
minetest.LIGHT_MAX+1,
horse.light_min.overworld,
horse.light_max.overworld,
30,
15000,
4,
@ -632,8 +642,8 @@ mcl_mobs:spawn_specific(
"Savanna_beach",
"Plains_beach",
},
9,
minetest.LIGHT_MAX+1,
donkey.light_min.overworld,
donkey.light_max.overworld,
30,
15000,
4,

View File

@ -10,14 +10,23 @@ local S = minetest.get_translator("mobs_mc")
--###################
local etime = 0
mcl_mobs.register_mob("mobs_mc:iron_golem", {
local iron_golem = {
description = S("Iron Golem"),
type = "npc",
spawn_class = "passive",
passive = false,
hp_min = 100,
hp_max = 100,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
breath_max = -1,
collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.69, 0.7},
visual = "mesh",
@ -93,7 +102,8 @@ mcl_mobs.register_mob("mobs_mc:iron_golem", {
end
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:iron_golem", iron_golem)
-- spawn eggs
@ -206,4 +216,3 @@ function mobs_mc.check_iron_golem_summon(pos)
end
end
end
mcl_mobs:non_spawn_specific("mobs_mc:iron_golem","overworld",0,minetest.LIGHT_MAX+1)

View File

@ -46,8 +46,7 @@ local function get_drops(self)
max = 1,})
end
end
mcl_mobs.register_mob("mobs_mc:llama", {
local llama = {
description = S("Llama"),
type = "animal",
spawn_class = "passive",
@ -56,8 +55,8 @@ mcl_mobs.register_mob("mobs_mc:llama", {
shoot_interval = 5.5,
arrow = "mobs_mc:llamaspit",
shoot_offset = 1, --3.5 *would* be a good value visually but it somehow messes with the projectiles trajectory
spawn_in_group_min = 2, -- was 4
spawn_in_group = 4, -- was 6 nerfed until we can cap them properly locally. this is a group size, not a per spawn attempt
spawn_in_group_min = 4,
spawn_in_group = 6,
head_swivel = "head.control",
bone_eye_height = 11,
@ -70,6 +69,16 @@ mcl_mobs.register_mob("mobs_mc:llama", {
hp_max = 30,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45},
visual = "mesh",
mesh = "mobs_mc_llama.b3d",
@ -249,7 +258,8 @@ mcl_mobs.register_mob("mobs_mc:llama", {
end
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:llama", llama)
mcl_entity_invs.register_inv("mobs_mc:llama","Llama",nil,true)
@ -288,8 +298,8 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ExtremeHillsM",
}, --FIXME: Needs Windswept Forest when that is added.
0,
minetest.LIGHT_MAX+1,
llama.light_min.overworld,
llama.light_max.overworld,
30,
15000,
5,

View File

@ -36,6 +36,16 @@ local ocelot = {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
head_swivel = "head.control",
bone_eye_height = 6.2,
head_eye_height = 0.4,
@ -183,8 +193,8 @@ mcl_mobs:spawn_specific(
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
ocelot.light_min.overworld,
ocelot.light_max.overworld,
30,
15000,
5,

View File

@ -124,8 +124,7 @@ local function check_perch(self,dtime)
end
end
end
mcl_mobs.register_mob("mobs_mc:parrot", {
local parrot = {
description = S("Parrot"),
type = "animal",
spawn_class = "passive",
@ -135,6 +134,16 @@ mcl_mobs.register_mob("mobs_mc:parrot", {
hp_max = 6,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
head_swivel = "head.control",
bone_eye_height = 1.1,
horrizonatal_head_height=0,
@ -219,7 +228,9 @@ mcl_mobs.register_mob("mobs_mc:parrot", {
return false --return false explicitly here. mcl_mobs checks for that
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:parrot", parrot)
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
mcl_mobs:spawn_specific(
@ -232,8 +243,8 @@ mcl_mobs:spawn_specific(
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
parrot.light_min.overworld,
parrot.light_max.overworld,
7,
30000,
1,

View File

@ -1,8 +1,7 @@
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:pig", {
local pig = {
description = S("Pig"),
type = "animal",
spawn_class = "passive",
@ -12,6 +11,16 @@ mcl_mobs.register_mob("mobs_mc:pig", {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-0.45, -0.01, -0.45, 0.45, 0.865, 0.45},
visual = "mesh",
mesh = "mobs_mc_pig.b3d",
@ -195,7 +204,8 @@ mcl_mobs.register_mob("mobs_mc:pig", {
return false
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:pig", pig)
mcl_mobs:spawn_specific(
"mobs_mc:pig",
@ -234,8 +244,8 @@ mcl_mobs:spawn_specific(
"Swampland",
"Swampland_shore"
},
9,
minetest.LIGHT_MAX+1,
pig.light_min.overworld,
pig.light_max.overworld,
30,
15000,
8,

View File

@ -42,6 +42,16 @@ local piglin = {
hp_max = 16,
xp_min = 9,
xp_max = 9,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = minetest.LIGHT_MAX+1,
the_end = 7
},
armor = {fleshy = 90},
damage = 4,
reach = 3,
@ -283,7 +293,6 @@ piglin_brute.group_attack = { "mobs_mc:piglin", "mobs_mc:piglin_brute" }
mcl_mobs.register_mob("mobs_mc:piglin_brute", piglin_brute)
mcl_mobs:non_spawn_specific("mobs_mc:piglin","overworld",0,7)
-- Regular spawning in the Nether
mcl_mobs:spawn_specific(
"mobs_mc:piglin",
@ -293,14 +302,14 @@ mcl_mobs:spawn_specific(
"Nether",
"CrimsonForest"
},
0,
minetest.LIGHT_MAX+1,
piglin.light_min.nether,
piglin.light_max.nether,
30,
6000,
3,
mcl_vars.mg_lava_nether_max,
mcl_vars.mg_nether_max)
mcl_mobs:non_spawn_specific("mobs_mc:sword_piglin","overworld",0,7)
mcl_mobs:spawn_specific(
"mobs_mc:sword_piglin",
"nether",
@ -309,8 +318,8 @@ mcl_mobs:spawn_specific(
"Nether",
"CrimsonForest"
},
0,
minetest.LIGHT_MAX+1,
sword_piglin.light_min.nether,
sword_piglin.light_max.nether,
30,
6000,
3,

View File

@ -23,6 +23,16 @@ pillager = {
hp_max = 24,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
breath_max = -1,
eye_height = 1.5,
shoot_interval = 3,
@ -122,4 +132,3 @@ pillager = {
mcl_mobs.register_mob("mobs_mc:pillager", pillager)
mcl_mobs.register_egg("mobs_mc:pillager", S("Pillager"), "#532f36", "#959b9b", 0)
mcl_mobs:non_spawn_specific("mobs_mc:pillager","overworld",0,7)

View File

@ -6,8 +6,7 @@ local S = minetest.get_translator("mobs_mc")
--################### POLARBEAR
--###################
mcl_mobs.register_mob("mobs_mc:polar_bear", {
local polar_bear = {
description = S("Polar Bear"),
type = "animal",
spawn_class = "passive",
@ -17,7 +16,17 @@ mcl_mobs.register_mob("mobs_mc:polar_bear", {
hp_max = 30,
xp_min = 1,
xp_max = 3,
breath_max = -1,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
breath_max = -1,
collisionbox = {-0.7, -0.01, -0.7, 0.7, 1.39, 0.7},
visual = "mesh",
mesh = "mobs_mc_polarbear.b3d",
@ -71,7 +80,8 @@ mcl_mobs.register_mob("mobs_mc:polar_bear", {
},
view_range = 16,
})
}
mcl_mobs.register_mob("mobs_mc:polar_bear", polar_bear)
mcl_mobs:spawn_specific(
@ -83,8 +93,8 @@ mcl_mobs:spawn_specific(
"IcePlainsSpikes",
"IcePlains",
},
0,
minetest.LIGHT_MAX+1,
polar_bear.light_min.overworld,
polar_bear.light_max.overworld,
30,
7000,
3,

View File

@ -14,6 +14,16 @@ local rabbit = {
hp_max = 3,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 9,
nether = 9,
the_end = 9
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2},
head_swivel = "head.control",
bone_eye_height = 2,
@ -145,8 +155,8 @@ mcl_mobs:spawn_specific(
"MegaTaiga",
"ColdTaiga",
},
9,
minetest.LIGHT_MAX+1,
rabbit.light_min.overworld,
rabbit.light_max.overworld,
30,
15000,
8,

View File

@ -18,6 +18,16 @@ local salmon = {
hp_max = 3,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
armor = 100,
spawn_in_group = 5,
tilt_swim = true,
@ -25,7 +35,7 @@ local salmon = {
visual = "mesh",
mesh = "extra_mobs_salmon.b3d",
textures = {
{"mobs_mc_salmon.png"}
{"extra_mobs_salmon.png"}
},
sounds = {
},
@ -217,8 +227,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
salmon.light_min.overworld,
salmon.light_max.overworld,
30,
4000,
3,

View File

@ -51,8 +51,7 @@ end
local gotten_texture = { "blank.png", "mobs_mc_sheep.png" }
--mcsheep
mcl_mobs.register_mob("mobs_mc:sheep", {
local sheep = {
description = S("Sheep"),
type = "animal",
spawn_class = "passive",
@ -61,6 +60,16 @@ mcl_mobs.register_mob("mobs_mc:sheep", {
hp_max = 8,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 9,
nether = 9,
the_end = 9
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45},
head_swivel = "head.control",
bone_eye_height = 3.3,
@ -314,7 +323,9 @@ mcl_mobs.register_mob("mobs_mc:sheep", {
return false
end
end,
})
}
--mcsheep
mcl_mobs.register_mob("mobs_mc:sheep", sheep)
mcl_mobs:spawn_specific(
"mobs_mc:sheep",
"overworld",
@ -357,8 +368,8 @@ mcl_mobs:spawn_specific(
"Swampland",
"Swampland_shore"
},
9,
minetest.LIGHT_MAX+1,
sheep.light_min.overworld,
sheep.light_max.overworld,
30,
15000,
3,

View File

@ -29,8 +29,7 @@ local function check_spot(pos)
return false
end
local pr = PseudoRandom(os.time()*(-334))
-- animation 45-80 is transition between passive and attack stance
mcl_mobs.register_mob("mobs_mc:shulker", {
local shulker = {
description = S("Shulker"),
type = "monster",
spawn_class = "hostile",
@ -43,6 +42,16 @@ mcl_mobs.register_mob("mobs_mc:shulker", {
hp_max = 30,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
armor = 150,
collisionbox = {-0.5, -0.01, -0.5, 0.5, 0.99, 0.5},
visual = "mesh",
@ -149,7 +158,9 @@ mcl_mobs.register_mob("mobs_mc:shulker", {
end
end
end,
})
}
-- animation 45-80 is transition between passive and attack stance
mcl_mobs.register_mob("mobs_mc:shulker", shulker)
-- bullet arrow (weapon)
mcl_mobs.register_arrow("mobs_mc:shulkerbullet", {
@ -178,7 +189,7 @@ mcl_mobs.register_arrow("mobs_mc:shulkerbullet", {
mcl_mobs.register_egg("mobs_mc:shulker", S("Shulker"), "#946694", "#4d3852", 0)
mcl_mobs:non_spawn_specific("mobs_mc:shulker","overworld",0,minetest.LIGHT_MAX+1)
--[[
mcl_mobs:spawn_specific(
"mobs_mc:shulker",

View File

@ -15,6 +15,16 @@ mcl_mobs.register_mob("mobs_mc:silverfish", {
hp_max = 8,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 11,
nether = 11,
the_end = 11,
},
armor = {fleshy = 100, arthropod = 100},
collisionbox = {-0.4, -0.01, -0.4, 0.4, 0.44, 0.4},
visual = "mesh",
@ -56,4 +66,3 @@ mcl_mobs.register_mob("mobs_mc:silverfish", {
})
mcl_mobs.register_egg("mobs_mc:silverfish", S("Silverfish"), "#6d6d6d", "#313131", 0)
mcl_mobs:non_spawn_specific("mobs_mc:silverfish","overworld",0,11)

View File

@ -20,6 +20,16 @@ local skeleton = {
hp_max = 20,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = minetest.LIGHT_MAX+1,
the_end = 7,
},
breath_max = -1,
armor = {undead = 100, fleshy = 100},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},
@ -309,8 +319,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
skeleton.light_min.overworld,
skeleton.light_max.overworld,
20,
17000,
2,
@ -326,8 +336,8 @@ mcl_mobs:spawn_specific(
{
"SoulsandValley",
},
0,
minetest.LIGHT_MAX+1,
skeleton.light_min.nether,
skeleton.light_max.nether,
30,
10000,
3,
@ -346,8 +356,8 @@ mcl_mobs:spawn_specific(
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
7,
stray.light_min.overworld,
stray.light_max.overworld,
20,
19000,
2,

View File

@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc")
--################### WITHER SKELETON
--###################
mcl_mobs.register_mob("mobs_mc:witherskeleton", {
local witherskeleton = {
description = S("Wither Skeleton"),
type = "monster",
spawn_class = "hostile",
@ -17,6 +17,16 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
hp_max = 20,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
breath_max = -1,
armor = {undead = 100, fleshy = 100},
pathfinding = 1,
@ -96,7 +106,8 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
fear_height = 4,
harmed_by_heal = true,
fire_resistant = true,
})
}
mcl_mobs.register_mob("mobs_mc:witherskeleton", witherskeleton)
--spawn
--[[]
@ -118,4 +129,3 @@ mcl_vars.mg_nether_max)
--]]
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "#141414", "#474d4d", 0)
mcl_mobs:non_spawn_specific("mobs_mc:witherskeleton","overworld",0,7)

View File

@ -70,6 +70,17 @@ local slime_big = {
hp_max = 16,
xp_min = 4,
xp_max = 4,
swamp_light_max = 7,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5},
textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}},
@ -197,7 +208,7 @@ local cave_min = mcl_vars.mg_overworld_min
local cave_max = water_level - 23
local swampy_biomes = {"Swampland", "MangroveSwamp"}
local swamp_light_max = 7
local swamp_min = water_level
local swamp_max = water_level + 27
@ -206,8 +217,8 @@ mcl_mobs:spawn_specific(
"overworld",
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_tiny.light_min.overworld,
slime_tiny.light_max.overworld,
30,
12000,
4,
@ -220,7 +231,7 @@ mcl_mobs:spawn_specific(
"ground",
swampy_biomes,
0,
swamp_light_max,
slime_tiny.swamp_light_max,
30,
12000,
4,
@ -232,8 +243,8 @@ mcl_mobs:spawn_specific(
"overworld",
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_small.light_min.overworld,
slime_small.light_max.overworld,
30,
8500,
4,
@ -246,7 +257,7 @@ mcl_mobs:spawn_specific(
"ground",
swampy_biomes,
0,
swamp_light_max,
slime_small.swamp_light_max,
30,
8500,
4,
@ -258,8 +269,8 @@ mcl_mobs:spawn_specific(
"overworld",
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_big.light_min.overworld,
slime_big.light_max.overworld,
30,
10000,
4,
@ -272,12 +283,13 @@ mcl_mobs:spawn_specific(
"ground",
swampy_biomes,
0,
swamp_light_max,
slime_big.swamp_light_max,
30,
10000,
4,
swamp_min,
swamp_max)
-- Magma cube
local magma_cube_big = {
description = S("Magma Cube"),
@ -287,6 +299,16 @@ local magma_cube_big = {
hp_max = 16,
xp_min = 4,
xp_max = 4,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1
},
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5},
textures = {{ "mobs_mc_magmacube.png", "mobs_mc_magmacube.png" }},
@ -393,8 +415,8 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
magma_cube_biomes,
0,
minetest.LIGHT_MAX+1,
magma_cube_tiny.light_min.nether,
magma_cube_tiny.light_max.nether,
30,
15000,
4,
@ -406,8 +428,8 @@ mcl_mobs:spawn_specific(
"nether",
"ground",
magma_cube_biomes,
0,
minetest.LIGHT_MAX+1,
magma_cube_small.light_min.nether,
magma_cube_small.light_max.nether,
30,
15500,
4,
@ -418,8 +440,8 @@ mcl_mobs:spawn_specific(
"mobs_mc:magma_cube_big",
"nether",
"ground",
magma_cube_biomes,
0,
magma_cube_big.light_min.nether,
magma_cube_big.light_max.nether,
minetest.LIGHT_MAX+1,
30,
16000,
@ -430,11 +452,6 @@ nether_max)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "#350000", "#fcfc00")
-- non_spawn_specific is typically for mobs who don't spawn in the overworld, or mobs that don't spawn
-- naturally. However, slimes are a particular case where they spawn under different conditions in the same
-- dimension.
mcl_mobs:non_spawn_specific("mobs_mc:slime_big","overworld",0,minetest.LIGHT_MAX+1)
mcl_mobs:non_spawn_specific("mobs_mc:magma_cube_big","overworld",0, minetest.LIGHT_MAX+1)
mcl_mobs.register_egg("mobs_mc:slime_big", S("Slime"), "#52a03e", "#7ebf6d")
-- FIXME: add spawn eggs for small and tiny slimes and magma cubes

View File

@ -20,7 +20,7 @@ local gotten_texture = {
"blank.png",
}
mcl_mobs.register_mob("mobs_mc:snowman", {
local snowman = {
description = S("Snow Golem"),
type = "npc",
spawn_class = "passive",
@ -135,7 +135,9 @@ mcl_mobs.register_mob("mobs_mc:snowman", {
end
end
end,
})
}
mcl_mobs.register_mob("mobs_mc:snowman", snowman)
local summon_particles = function(obj)
local lua = obj:get_luaentity()
@ -197,4 +199,3 @@ end
-- Spawn egg
mcl_mobs.register_egg("mobs_mc:snowman", S("Snow Golem"), "#f2f2f2", "#fd8f47", 0)
mcl_mobs:non_spawn_specific("mobs_mc:snowman","overworld",0,minetest.LIGHT_MAX+1)

View File

@ -43,6 +43,16 @@ local spider = {
hp_max = 16,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
armor = {fleshy = 100, arthropod = 100},
on_spawn = function(self)
self.object:set_properties({visual_size={x=1,y=1}})
@ -284,8 +294,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
spider.light_min.overworld,
spider.light_max.overworld,
30,
17000,
2,

View File

@ -6,7 +6,7 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs.register_mob("mobs_mc:squid", {
local squid = {
description = S("Squid"),
type = "animal",
spawn_class = "water",
@ -16,6 +16,16 @@ mcl_mobs.register_mob("mobs_mc:squid", {
hp_max = 10,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
armor = 100,
-- FIXME: If the squid is near the floor, it turns black
collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.9, 0.4},
@ -55,7 +65,9 @@ mcl_mobs.register_mob("mobs_mc:squid", {
view_range = 16,
runaway = true,
fear_height = 4,
})
}
mcl_mobs.register_mob("mobs_mc:squid", squid)
-- TODO: Behaviour: squirt
@ -208,8 +220,8 @@ mcl_mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
squid.light_min.overworld,
squid.light_max.overworld,
30,
5500,
3,

View File

@ -18,6 +18,16 @@ local strider = {
hp_max = 20,
xp_min = 9,
xp_max = 9,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
armor = {fleshy = 90},
attack_type = "dogfight",
damage = 2,
@ -246,4 +256,3 @@ mcl_mobs:spawn_setup({
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:strider", S("Strider"), "#000000", "#FF0000", 0)
mcl_mobs:non_spawn_specific("mobs_mc:strider","nether",0,minetest.LIGHT_MAX+1)

View File

@ -66,8 +66,18 @@ local tropical_fish = {
hp_max = 3,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
armor = 100,
spawn_in_group = 4, -- was 9. nerfed until aquatics use own cap rather than animal, and it represents pack size, not per spawn attempt
spawn_in_group = 9,
tilt_swim = true,
collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2},
visual = "mesh",
@ -180,8 +190,8 @@ mcl_mobs:spawn_specific(
"JungleM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
tropical_fish.light_min.overworld,
tropical_fish.light_max.overworld,
30,
4000,
3,

View File

@ -8,8 +8,7 @@ local S = minetest.get_translator("mobs_mc")
--###################
--################### VEX
--###################
mcl_mobs.register_mob("mobs_mc:vex", {
local vex = {
description = S("Vex"),
type = "monster",
spawn_class = "hostile",
@ -90,9 +89,9 @@ mcl_mobs.register_mob("mobs_mc:vex", {
end,
fly = true,
makes_footstep_sound = false,
})
}
mcl_mobs.register_mob("mobs_mc:vex", vex)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:vex", S("Vex"), "#7a90a4", "#e8edf1", 0)
mcl_mobs:non_spawn_specific("mobs_mc:vex","overworld",0,7)

View File

@ -617,13 +617,6 @@ local function set_textures(self)
self.object:set_properties({textures=badge_textures})
end
-- TODO Pass in self and if nitwit, go to bed later.
local function is_night()
local tod = minetest.get_timeofday()
tod = ( tod * 24000 ) % 24000
return tod > 17500 or tod < 6500
end
function get_activity(tod)
-- night hours = tod > 18541 or tod < 5458
if not tod then
@ -633,8 +626,8 @@ function get_activity(tod)
local lunch_start = 11000
local lunch_end = 13500
local work_start = 7500
local work_end = 16000
local work_start = 7000
local work_end = 16500
local activity = nil
if weather_mod and mcl_weather.get_weather() == "thunder" then
@ -642,7 +635,7 @@ function get_activity(tod)
activity = SLEEP
elseif (tod > work_start and tod < lunch_start) or (tod > lunch_end and tod < work_end) then
activity = WORK
elseif is_night() then
elseif mcl_beds.is_night() then
activity = SLEEP
elseif tod > lunch_start and tod < lunch_end then
activity = GATHERING
@ -836,7 +829,7 @@ local function go_home(entity, sleep)
else
--minetest.log("Need to walk to home")
end
end, true)
end)
end
end
@ -1173,7 +1166,6 @@ local function do_work (self)
self.order = nil
return
end
self:gopath(jobsite, function(self, jobsite)
if not self then
--mcl_log("missing self. not good")
@ -1317,7 +1309,7 @@ local function do_activity (self)
local jobsite_valid = false
if not is_night() then
if not mcl_beds.is_night() then
if self.order == SLEEP then self.order = nil end
if not validate_jobsite(self) then
@ -1939,13 +1931,23 @@ end)
--[=======[ MOB REGISTRATION AND SPAWNING ]=======]
mcl_mobs.register_mob("mobs_mc:villager", {
local villager = {
description = S("Villager"),
type = "npc",
spawn_class = "passive",
passive = true,
hp_min = 20,
hp_max = 20,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
head_swivel = "head.control",
bone_eye_height = 6.3,
head_eye_height = 2.2,
@ -2163,7 +2165,9 @@ mcl_mobs.register_mob("mobs_mc:villager", {
mcl_util.replace_mob(self.object, "mobs_mc:witch")
return true
end,
})
}
mcl_mobs.register_mob("mobs_mc:villager", villager)
--[[
@ -2199,5 +2203,4 @@ mobs_mc.water_level+1,
mcl_vars.mg_overworld_max)
--]]
-- spawn eggs
mcl_mobs:non_spawn_specific("mobs_mc:villager","overworld", 0, minetest.LIGHT_MAX+1)
mcl_mobs.register_egg("mobs_mc:villager", S("Villager"), "#563d33", "#bc8b72", 0)

View File

@ -13,7 +13,7 @@ local pr = PseudoRandom(os.time()*666)
local spawned_vexes = {} --this is stored locally so the mobs engine doesn't try to store it in staticdata
mcl_mobs.register_mob("mobs_mc:evoker", {
local evoker = {
description = S("Evoker"),
type = "monster",
spawn_class = "hostile",
@ -24,6 +24,16 @@ mcl_mobs.register_mob("mobs_mc:evoker", {
hp_max = 24,
xp_min = 10,
xp_max = 10,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
head_swivel = "head.control",
bone_eye_height = 6.3,
head_eye_height = 2.2,
@ -86,8 +96,8 @@ mcl_mobs.register_mob("mobs_mc:evoker", {
},
view_range = 16,
fear_height = 4,
})
}
mcl_mobs.register_mob("mobs_mc:evoker", evoker)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:evoker", S("Evoker"), "#959b9b", "#1e1c1a", 0)
mcl_mobs:non_spawn_specific("mobs_mc:evoker","overworld",0,7)

View File

@ -6,7 +6,7 @@
local S = minetest.get_translator("mobs_mc")
local mod_bows = minetest.get_modpath("mcl_bows") ~= nil
mcl_mobs.register_mob("mobs_mc:illusioner", {
local illusioner = {
description = S("Illusioner"),
type = "monster",
spawn_class = "hostile",
@ -25,6 +25,16 @@ mcl_mobs.register_mob("mobs_mc:illusioner", {
hp_max = 32,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_illusioner.b3d",
@ -63,7 +73,7 @@ mcl_mobs.register_mob("mobs_mc:illusioner", {
},
view_range = 16,
fear_height = 4,
})
}
mcl_mobs.register_mob("mobs_mc:illusioner", illusioner)
mcl_mobs.register_egg("mobs_mc:illusioner", S("Illusioner"), "#3f5cbb", "#8a8686", 0)
mcl_mobs:non_spawn_specific("mobs_mc:illusioner","overworld",0,7)

View File

@ -9,8 +9,7 @@ local S = minetest.get_translator("mobs_mc")
--################### VINDICATOR
--###################
mcl_mobs.register_mob("mobs_mc:vindicator", {
local vindicator = {
description = S("Vindicator"),
type = "monster",
spawn_class = "hostile",
@ -20,6 +19,16 @@ mcl_mobs.register_mob("mobs_mc:vindicator", {
hp_max = 24,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_vindicator.b3d",
@ -74,8 +83,9 @@ mcl_mobs.register_mob("mobs_mc:vindicator", {
},
view_range = 16,
fear_height = 4,
})
}
mcl_mobs.register_mob("mobs_mc:vindicator", vindicator)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:vindicator", S("Vindicator"), "#959b9b", "#275e61", 0)
mcl_mobs:non_spawn_specific("mobs_mc:vindicator","overworld",0,7)

View File

@ -25,7 +25,7 @@ local professions = {
nitwit = "mobs_mc_villager.png",
}
mcl_mobs.register_mob("mobs_mc:villager_zombie", {
local villager_zombie = {
description = S("Zombie Villager"),
type = "monster",
spawn_class = "hostile",
@ -34,6 +34,16 @@ mcl_mobs.register_mob("mobs_mc:villager_zombie", {
hp_max = 20,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
breath_max = -1,
armor = {undead = 90, fleshy = 90},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
@ -138,7 +148,8 @@ mcl_mobs.register_mob("mobs_mc:villager_zombie", {
fear_height = 4,
harmed_by_heal = true,
attack_npcs = true,
})
}
mcl_mobs.register_mob("mobs_mc:villager_zombie", villager_zombie)
mcl_mobs:spawn_specific(
"mobs_mc:villager_zombie",
@ -222,8 +233,8 @@ mcl_mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
villager_zombie.light_min.overworld,
villager_zombie.light_max.overworld,
30,
4090,
4,

View File

@ -21,6 +21,16 @@ mcl_mobs.register_mob("mobs_mc:witch", {
hp_max = 26,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7,
},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_witch.b3d",
@ -106,5 +116,5 @@ mcl_mobs.register_arrow("mobs_mc:potion_arrow", {
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:witch", S("Witch"), "#340000", "#51a03e", 0, true)
mcl_mobs:non_spawn_specific("mobs_mc:witch","overworld",0,7)
mcl_wip.register_wip_item("mobs_mc:witch")

View File

@ -17,6 +17,16 @@ mcl_mobs.register_mob("mobs_mc:wither", {
hp_min = 300,
xp_min = 50,
xp_max = 50,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7
},
armor = {undead = 80, fleshy = 100},
-- This deviates from MC Wiki's size, which makes no sense
collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9},
@ -132,4 +142,3 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, true)
mcl_wip.register_wip_item("mobs_mc:wither")
mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1)

View File

@ -16,6 +16,16 @@ local wolf = {
hp_max = 8,
xp_min = 1,
xp_max = 3,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = minetest.LIGHT_MAX+1,
nether = minetest.LIGHT_MAX+1,
the_end = minetest.LIGHT_MAX+1,
},
passive = false,
group_attack = true,
spawn_in_group = 8,
@ -226,8 +236,8 @@ mcl_mobs:spawn_specific(
minetest.LIGHT_MAX+1,
30,
9000,
7,
mobs_mc.water_level+3,
wolf.light_min.overworld,
wolf.light_max.overworld,
mcl_vars.mg_overworld_max)
mcl_mobs.register_egg("mobs_mc:wolf", S("Wolf"), "#d7d3d3", "#ceaf96", 0)

View File

@ -53,6 +53,16 @@ local zombie = {
hp_max = 20,
xp_min = 5,
xp_max = 5,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = 7,
the_end = 7
},
head_swivel = "head.control",
bone_eye_height = 6.3,
head_eye_height = 2.2,
@ -240,8 +250,8 @@ mcl_mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
zombie.light_min.overworld,
zombie.light_max.overworld,
30,
6000,
4,
@ -329,8 +339,8 @@ mcl_mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
baby_zombie.light_min.overworld,
baby_zombie.light_max.overworld,
30,
60000,
4,
@ -345,8 +355,8 @@ mcl_mobs:spawn_specific(
{
"Desert",
},
0,
7,
husk.light_min.overworld,
husk.light_max.overworld,
30,
6500,
4,
@ -359,8 +369,8 @@ mcl_mobs:spawn_specific(
{
"Desert",
},
0,
7,
baby_husk.light_min.overworld,
baby_husk.light_max.overworld,
30,
65000,
4,

View File

@ -20,6 +20,16 @@ local pigman = {
hp_max = 20,
xp_min = 6,
xp_max = 6,
light_min = {
overworld = 0,
nether = 0,
the_end = 0
},
light_max = {
overworld = 7,
nether = minetest.LIGHT_MAX+1,
the_end = 7
},
armor = {undead = 90, fleshy = 90},
attack_type = "dogfight",
group_attack = { "mobs_mc:pigman", "mobs_mc:baby_pigman" },
@ -153,4 +163,3 @@ mcl_vars.mg_nether_max)
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:pigman", S("Zombie Pigman"), "#ea9393", "#4c7129", 0)
mcl_mobs:non_spawn_specific("mobs_mc:pigman","overworld",0,minetest.LIGHT_MAX+1)

View File

@ -226,7 +226,7 @@ if mcl_weather.allow_abm then
}
for a=1, #around do
local apos = vector.add(pos, around[a])
if mcl_weather.is_outdoor(apos) and mcl_weather.has_rain(apos) then
if mcl_weather.is_outdoor(apos) then
minetest.remove_node(pos)
minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 8, gain = 0.1}, true)
return
@ -244,7 +244,7 @@ if mcl_weather.allow_abm then
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
-- Rain is equivalent to a water bottle
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) and mcl_weather.has_rain(pos) then
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
if node.name == "mcl_cauldrons:cauldron" then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_1"})
elseif node.name == "mcl_cauldrons:cauldron_1" then
@ -267,7 +267,7 @@ if mcl_weather.allow_abm then
interval = 22.0,
chance = 3,
action = function(pos, node, active_object_count, active_object_count_wider)
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) and mcl_weather.has_rain(pos) then
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
if node.name == "mcl_farming:soil" then
minetest.set_node(pos, {name="mcl_farming:soil_wet"})
end

View File

@ -1,7 +1,7 @@
local mods_loaded = false
local NIGHT_VISION_RATIO = 0.45
local water_color = "#3F76E4"
local water_color = "#0b4880"
local mg_name = minetest.get_mapgen_setting("mg_name")
@ -125,14 +125,7 @@ mcl_weather.skycolor = {
local pos = player:get_pos()
local dim = mcl_worlds.pos_to_dimension(pos)
local has_weather = (mcl_worlds.has_weather(pos) and (mcl_weather.state == "snow" or mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_snow(pos)) or ((mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_rain(pos))
local checkname = minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name
if minetest.get_item_group(checkname, "water") ~= 0 then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then water_color = biome._mcl_waterfogcolor end
if not biome then water_color = "#3F76E4" end
if checkname == "mclx_core:river_water_source" or checkname == "mclx_core:river_water_flowing" then water_color = "#0084FF" end
if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then
player:set_sky({ type = "regular",
sky_color = {
day_sky = water_color,

View File

@ -297,7 +297,7 @@ awards.register_achievement("mcl:whatAdeal", {
awards.register_achievement("mcl:tacticalFishing", {
title = S("Tactical Fishing"),
description = S("Catch a fish... without a fishing rod!"),
icon = "mcl_buckets_pufferfish_bucket.png",
icon = "pufferfish_bucket.png",
type = "Advancement",
group = "Husbandry",
})
@ -305,7 +305,7 @@ awards.register_achievement("mcl:tacticalFishing", {
awards.register_achievement("mcl:cutestPredator", {
title = S("The Cutest Predator"),
description = S("Catch an Axolotl with a bucket!"),
icon = "mcl_buckets_axolotl_bucket.png",
icon = "axolotl_bucket.png",
type = "Advancement",
group = "Husbandry",
})

View File

@ -225,8 +225,8 @@ local woods = {
{ "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Button") },
{ "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Button") },
{ "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "mcl_crimson_crimson_hyphae_wood.png", S("Crimson Button") },
{ "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "mcl_crimson_warped_hyphae_wood.png", S("Warped Button") },
{ "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "crimson_hyphae_wood.png", S("Crimson Button") },
{ "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "warped_hyphae_wood.png", S("Warped Button") },
}
for w=1, #woods do

View File

@ -477,19 +477,6 @@ mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_black")
mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_brown")
mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_light_blue")
mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_pink")
-- Bamboo
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_endcap")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_1")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_2")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_3")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_door")
mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_trapdoor")
mesecon.register_mvps_unsticky("mcl_signs:wall_sign_bamboo")
mesecon.register_mvps_unsticky("mcl_bamboo:scaffolding")
-- Beds
mesecon.register_mvps_unsticky("mcl_beds:bed_black_top")
mesecon.register_mvps_unsticky("mcl_beds:bed_black_bottom")

View File

@ -223,8 +223,8 @@ local woods = {
{ "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Pressure Plate") },
{ "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Pressure Plate") },
{ "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "mcl_crimson_crimson_hyphae_wood.png", S("Crimson Pressure Plate") },
{ "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "mcl_crimson_warped_hyphae_wood.png", S("Warped Pressure Plate") },
{ "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "crimson_hyphae_wood.png", S("Crimson Pressure Plate") },
{ "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "warped_hyphae_wood.png", S("Warped Pressure Plate") },
}
for w=1, #woods do

View File

@ -1,19 +0,0 @@
# textdomain: mcl_amethyst
Amethyst Cluster=Aglomerado de Ametista
Amethyst Cluster is the final growth of amethyst bud.=O aglomerado de ametista é o final do crescimento do broto de ametista.
Amethyst Shard=Fragmento de Ametista
An amethyst shard is a crystalline mineral.=Um fragmento de ametista é um mineral cristalino.
Block of Amethyst=Bloco de Ametista
Budding Amethyst=Ametista Brotando
Calcite=Calcita
Calcite can be found as part of amethyst geodes.=Calcita pode ser encontrada como parte dos geodos de ametista.
Large Amethyst Bud=Broto de Ametista Grande
Large Amethyst Bud is the third growth of amethyst bud.=Broto de Ametista Grande é a terceira etapa de crescimento do broto de ametista.
Medium Amethyst Bud=Broto de Ametista Médio
Medium Amethyst Bud is the second growth of amethyst bud.=Broto de Ametista Médio é a segunda etapa de crescimento do broto de ametista.
Small Amethyst Bud=Broto de Ametista Pequeno
Small Amethyst Bud is the first growth of amethyst bud.=Broto de Ametista Pequeno é a primeira etapa de crescimento do broto de ametista.
The Block of Amethyst is a decoration block crafted from amethyst shards.=O bloco de ametista é um bloco decorativo feito a partir de fragmentos de ametista.
The Budding Amethyst can grow amethyst=A ametista brotando pode crescer ametista.
Tinted Glass=Vidro Tingido
Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Vidro tingido é um tipo de vidro que bloqueia luzes enquanto é visualmente transparente.

View File

@ -1,16 +0,0 @@
# textdomain: mcl_anvils
Set Name=Colocar nome
Repair and Name=Reparar e Nomear
Inventory=Inventário
Anvil=Bigorna
The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!=A bigorna permite você reparar ferramentas e armaduras e nomear itens. No entanto, possui uma durabilidade limitada. Não a deixe cair sob sua cabeça, pode ser doloroso!
To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Para usar a bigorna, aperte-a com o botão direito. Uma bigorna possui 2 espaços de entrada (a esquerda) e um espaço de saída.
To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.=Para renomear itens, coloque-o em um espaço de entrada enquanto mantém o outro vazio. Digite um nome e aperte enter ou "Colocar nome". Retire o item renomeado do espaço de saída.
There are two possibilities to repair tools (and armor):=Há duas possibilidades de reparar ferramentas (e armaduras):
• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.= Ferramenta + Ferramenta: Coloque duas ferramentas do mesmo tipo nos espaços de entrada. A durabilidade da ferramenta reparada é a soma da durabilidade de ambas ferramentas utilizadas acrescido de um bônus de 12%.
• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.=Ferramenta + Material: Algumas ferramentas também podem ser reparadas combinando com o material da qual ela é feita. Por exemplo, picaretas de ferro podem ser reparadas com lingotes de ferro. Este repara a ferramenta por 25%.
Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Armadura conta como uma ferramenta. É possível reparar e nomear uma ferramenta em uma única etapa.
Slightly Damaged Anvil=Bigorna danificada
The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.=A bigorna tem durabilidade limitada e 3 níveis de dano: não danificada, danificada, muito danificada. Toda vez que você reparar ou nomear algo, há uma chance de 12% da bigorna ser danificada. Bigornas também possuem uma chance de serem danificadas quando cai por mais de 1 bloco. Se uma bigorna muito danificada sofre dano, ela é destruída.
Very Damaged Anvil=Bigorna muito danificada
Repair and rename items=Reparar e renomear itens

View File

@ -1,48 +0,0 @@
# textdomain: mcl_armor
This is a piece of equippable armor which reduces the amount of damage you receive.=
To equip it, put it on the corresponding armor slot in your inventory menu.=
Leather Cap=Chapéu de Couro
Iron Helmet=Capacete de Ferro
Golden Helmet=Capacete de Ouro
Diamond Helmet=Capacete de Diamante
Chain Helmet=Capacete de Cota de Malha
Netherite Helmet=Capacete de Netherite
Leather Tunic=Túnica de Couro
Iron Chestplate=Peitoral de Ferro
Golden Chestplate=Peitoral de Ouro
Diamond Chestplate=Peitoral de Diamante
Chain Chestplate=Peitoral de Cota de Malha
Netherite Chestplate=Peitoral de Netherite
Leather Pants=Calças de Couro
Iron Leggings=Perneiras de Ferro
Golden Leggings=Perneiras de Ouro
Diamond Leggings=Perneiras de Diamante
Chain Leggings=Perneiras de Cota de Malha
Netherite Leggings=Perneiras de Netherite
Leather Boots=Botas de Couro
Iron Boots=Botas de Ferro
Golden Boots=Botas de Ouro
Diamond Boots=Botas de Diamante
Chain Boots=Botas de Cota de Malha
Netherite Boots=Botas de Netherite
Elytra=Elytra
#Translations of enchantements
Increases underwater mining speed.=Aumenta a velocidade de mineração subaquática.
Blast Protection=Proteção Contra Explosão
Reduces explosion damage and knockback.=Reduz o dano e recúo de explosões.
Curse of Binding=Maldição do Vínculo
Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Item não pode ser removido do espaço de armadura, exceto devido à morte, quebra ou no Modo Criativo.
Feather Falling=Pena Caindo
Reduces fall damage.=Reduz o dano de quedas.
Fire Protection=Proteçao Contra Fogo
Reduces fire damage.=Reduz o dano causado por fogo.
Shooting consumes no regular arrows.=Disparar não consome flechas normais.
Shoot 3 arrows at the cost of one.=Dispare 3 flechas ao custo de uma.
Projectile Protection=Proteção Contra Projéteis
Reduces projectile damage.=Reduz o dano causado por projéteis.
Protection=Proteção
Reduces most types of damage by 4% for each level.=Reduz a maioria dos tipos de dano por 4% para cada nível.
Thorns=Espinhos
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflete parte do dano tomado aos custos de reduzir a durabilidade com cada uso.
Aqua Affinity=Afinidade Aqua

View File

@ -51,8 +51,8 @@ minetest.register_node("mcl_armor_stand:armor_stand", {
_doc_items_usagehelp = S("Just place an armor item on the armor stand. To take the top piece of armor from the armor stand, select your hand and use the place key on the armor stand."),
drawtype = "mesh",
mesh = "3d_armor_stand.obj",
inventory_image = "mcl_armor_stand_item.png",
wield_image = "mcl_armor_stand_item.png",
inventory_image = "3d_armor_stand_item.png",
wield_image = "3d_armor_stand_item.png",
tiles = {"default_wood.png", "mcl_stairs_stone_slab_top.png"},
paramtype = "light",
paramtype2 = "facedir",

View File

@ -1,5 +0,0 @@
# textdomain: mcl_armor_stand
Armor Stand=Suporte de Armadura
An armor stand is a decorative object which can display different pieces of armor. Anything which players can wear as armor can also be put on an armor stand.=O suporte de armadura é um objeto decorativo que pode exibir diferentes partes de armadura. Qualquer coisa que o jogador pode vestir como armadura também pode ser colocado no suporte de armadura.
Just place an armor item on the armor stand. To take the top piece of armor from the armor stand, select your hand and use the place key on the armor stand.=Apenas coloque um item de armadura no suporte de armadura. Para retirar a peça de armadura superior do suporte de armadura, selecione suas mãos e aperte o botão de colocar no suporte de armadura.
Displays pieces of armor=Exibe peças de armadura

View File

@ -29,7 +29,7 @@ local bamboo_def = {
tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo.png"},
drawtype = "nodebox",
paramtype = "light",
groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3},
groups = {handy = 1, axey = 1, choppy = 1, flammable = 3},
sounds = node_sound,
drop = {
@ -293,6 +293,7 @@ local bamboo_block_def = {
return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under)))
end,
}
minetest.register_node("mcl_bamboo:bamboo_block", bamboo_block_def)

View File

@ -35,9 +35,9 @@ if minetest.get_modpath("mcl_flowerpots") then
if mcl_flowerpots ~= nil then
-- Flower-potted Bamboo...
local flwr_name = BAMBOO
local flwr_def = { name = "bamboo_plant",
desc = S("Bamboo"),
image = "mcl_bamboo_bamboo_fpm.png", -- use with "register_potted_cube"
local flwr_def = {name = "bamboo_plant",
desc = S("Bamboo"),
image = "mcl_bamboo_bamboo_fpm.png", -- use with "register_potted_cube"
-- "mcl_bamboo_flower_pot.png", -- use with "register_potted_flower"
}
@ -53,11 +53,11 @@ if minetest.get_modpath("mcl_doors") then
local bot_door_tiles = {}
if BROKEN_DOORS then
top_door_tiles = { "mcl_bamboo_door_top_alt.png", "mcl_bamboo_door_top.png" }
bot_door_tiles = { "mcl_bamboo_door_bottom_alt.png", "mcl_bamboo_door_bottom.png" }
top_door_tiles = {"mcl_bamboo_door_top_alt.png", "mcl_bamboo_door_top.png"}
bot_door_tiles = {"mcl_bamboo_door_bottom_alt.png", "mcl_bamboo_door_bottom.png"}
else
top_door_tiles = { "mcl_bamboo_door_top.png", "mcl_bamboo_door_top.png" }
bot_door_tiles = { "mcl_bamboo_door_bottom.png", "mcl_bamboo_door_bottom.png" }
top_door_tiles = {"mcl_bamboo_door_top.png", "mcl_bamboo_door_top.png"}
bot_door_tiles = {"mcl_bamboo_door_bottom.png", "mcl_bamboo_door_bottom.png"}
end
local name = "mcl_bamboo:bamboo_door"
@ -65,7 +65,7 @@ if minetest.get_modpath("mcl_doors") then
description = S("Bamboo Door."),
inventory_image = "mcl_bamboo_door_wield.png",
wield_image = "mcl_bamboo_door_wield.png",
groups = { handy = 1, axey = 1, material_wood = 1, flammable = -1 },
groups = {handy = 1, axey = 1, material_wood = 1, flammable = -1},
_mcl_hardness = 3,
_mcl_blast_resistance = 3,
tiles_bottom = bot_door_tiles,
@ -86,7 +86,7 @@ if minetest.get_modpath("mcl_doors") then
_doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."),
wield_image = "mcl_bamboo_trapdoor_side.png",
inventory_image = "mcl_bamboo_trapdoor_side.png",
groups = { handy = 1, axey = 1, mesecon_effector_on = 1, material_wood = 1, flammable = -1 },
groups = {handy = 1, axey = 1, mesecon_effector_on = 1, material_wood = 1, flammable = -1},
_mcl_hardness = 3,
_mcl_blast_resistance = 3,
sounds = mcl_sounds.node_sound_wood_defaults(),
@ -137,7 +137,7 @@ if minetest.get_modpath("mcl_stairs") then
fire_flammability = 20
}
minetest.override_item(bamboo_plank_slab, { groups = node_groups })
minetest.override_item(bamboo_plank_slab, {groups = node_groups})
end
end
@ -168,13 +168,13 @@ if minetest.get_modpath("mesecons_pressureplates") then
mesecon.register_pressure_plate(
"mcl_bamboo:pressure_plate_bamboo_wood",
S("Bamboo Pressure Plate"),
{ "mcl_bamboo_bamboo_plank.png" },
{ "mcl_bamboo_bamboo_plank.png" },
{"mcl_bamboo_bamboo_plank.png"},
{"mcl_bamboo_bamboo_plank.png"},
"mcl_bamboo_bamboo_plank.png",
nil,
{ { BAMBOO_PLANK, BAMBOO_PLANK } },
{{BAMBOO_PLANK, BAMBOO_PLANK}},
mcl_sounds.node_sound_wood_defaults(),
{ axey = 1, material_wood = 1 },
{axey = 1, material_wood = 1},
nil,
S("A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it."))
@ -204,8 +204,8 @@ if minetest.get_modpath("mcl_fences") then
mcl_bamboo.mcl_log("Fences Section Entrance. Modpath exists.")
local id = "bamboo_fence"
local wood_groups = { handy = 1, axey = 1, flammable = 2, fence_wood = 1, fire_encouragement = 5, fire_flammability = 20 }
local wood_connect = { "group:fence_wood" }
local wood_groups = {handy = 1, axey = 1, flammable = 2, fence_wood = 1, fire_encouragement = 5, fire_flammability = 20}
local wood_connect = {"group:fence_wood"}
local fence_id = mcl_fences.register_fence(id, S("Bamboo Fence"), "mcl_bamboo_fence_bamboo.png", wood_groups,
2, 15, wood_connect, node_sound)
@ -224,7 +224,7 @@ if minetest.get_modpath("mesecons_button") then
"mcl_bamboo_bamboo_plank.png",
BAMBOO_PLANK,
node_sound,
{ material_wood = 1, handy = 1, pickaxey = 1, flammable = 3, fire_flammability = 20, fire_encouragement = 5, },
{material_wood = 1, handy = 1, pickaxey = 1, flammable = 3, fire_flammability = 20, fire_encouragement = 5, },
1,
false,
S("A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."),
@ -253,24 +253,24 @@ minetest.register_node(SCAFFOLDING_NAME, {
description = S("Scaffolding"),
doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."),
doc_items_hidden = false,
tiles = { "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png" },
tiles = {"mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png"},
drawtype = "nodebox",
paramtype = "light",
use_texture_alpha = "clip",
node_box = {
type = "fixed",
fixed = {
{ -0.5, 0.375, -0.5, 0.5, 0.5, 0.5 },
{ -0.5, -0.5, -0.5, -0.375, 0.5, -0.375 },
{ 0.375, -0.5, -0.5, 0.5, 0.5, -0.375 },
{ 0.375, -0.5, 0.375, 0.5, 0.5, 0.5 },
{ -0.5, -0.5, 0.375, -0.375, 0.5, 0.5 },
{-0.5, 0.375, -0.5, 0.5, 0.5, 0.5},
{-0.5, -0.5, -0.5, -0.375, 0.5, -0.375},
{0.375, -0.5, -0.5, 0.5, 0.5, -0.375},
{0.375, -0.5, 0.375, 0.5, 0.5, 0.5},
{-0.5, -0.5, 0.375, -0.375, 0.5, 0.5},
}
},
selection_box = {
type = "fixed",
fixed = {
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 },
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
},
buildable_to = false,
@ -279,7 +279,7 @@ minetest.register_node(SCAFFOLDING_NAME, {
climbable = true,
physical = true,
node_placement_prediction = "",
groups = { handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, dig_by_piston = 1, falling_node = 1, stack_falling = 1 },
groups = {handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, falling_node = 1, stack_falling = 1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 0,
_mcl_hardness = 0,
@ -319,7 +319,7 @@ minetest.register_node(SCAFFOLDING_NAME, {
local dir = vector.subtract(pointed.under, pointed.above)
local wdir = minetest.dir_to_wallmounted(dir)
if wdir == 1 then
minetest.set_node(pointed.above, { name = SCAFFOLDING_NAME, param2 = 0 })
minetest.set_node(pointed.above, {name = SCAFFOLDING_NAME, param2 = 0})
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item(1)
end

View File

@ -67,32 +67,6 @@ end
local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap"
-- For when I learn more about the pistons...
function mcl_bamboo.break_orphaned(pos)
mcl_bamboo.mcl_log("Break_Orphaned called.")
local node_below = minetest.get_node(vector.offset(pos, 0, -1, 0))
local node_name = node_below.name
-- short circuit checks.
if mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then
return
end
-- dig the node.
minetest.remove_node(pos) -- if that fails, remove the node
local istack = ItemStack("mcl_bamboo:bamboo")
local sound_params = {
pos = pos,
gain = 1.0, -- default
max_hear_distance = 10, -- default, uses a Euclidean metric
}
minetest.remove_node(pos)
minetest.sound_play(mcl_sounds.node_sound_wood_defaults().dug, sound_params, true)
minetest.add_item(pos, istack)
end
--]]
function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
local node_above = minetest.get_node(vector.offset(pos, 0, 1, 0))
mcl_bamboo.mcl_log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied))
@ -187,7 +161,7 @@ function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
-- equals top of the stalk before the cap
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(vector.offset(chk_pos, 0, 1, 0), { name = BAMBOO_ENDCAP_NAME })
minetest.set_node(vector.offset(chk_pos, 0, 1, 0), {name = BAMBOO_ENDCAP_NAME})
return true -- returning true means use up the bonemeal.
else
return false
@ -204,13 +178,13 @@ function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
if node_name == "air" then
-- here we can check to see if we can do up to 2 bamboo shoots onto the stalk
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
minetest.set_node(chk_pos, {name = node_below})
-- handle growing a second node.
if grow_amount == 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
minetest.set_node(chk_pos, {name = node_below})
end
end
return true -- exit out with a success. We've added 1-2 nodes, per the wiki.
@ -236,7 +210,7 @@ function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
if node_name == "air" and above_node_name == "air" then
if height - 1 == dist then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(chk_pos, { name = BAMBOO_ENDCAP_NAME })
minetest.set_node(chk_pos, {name = BAMBOO_ENDCAP_NAME})
end
end
break
@ -248,13 +222,13 @@ function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist)
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
minetest.set_node(chk_pos, {name = node_below})
-- handle growing a second node. (1 in 32 chance.)
if grow_amount == 2 and dist <= height - 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
minetest.set_node(chk_pos, {name = node_below})
end
end
break
@ -277,7 +251,7 @@ function mcl_bamboo.add_groups(name, ...)
return add_all(...)
end
addall(...)
return minetest.override_item(name, { groups = groups })
return minetest.override_item(name, {groups = groups})
end
function mcl_bamboo.mcl_log(m, l)

View File

@ -26,7 +26,6 @@ dofile(minetest.get_modpath(modname) .. "/recipes.lua")
--ABMs
minetest.register_abm({
label = "Bamboo Grow",
nodenames = mcl_bamboo.bamboo_index,
interval = 10,
chance = 20,
@ -35,38 +34,6 @@ minetest.register_abm({
end,
})
--[[ TODO: Figure out how to make this work:
local function dropper_call(node, pushdir, stack, stackid)
mcl_bamboo.mcl_log("mvps_dropper call for bamboo:")
-- mcl_bamboo.break_orphaned()
mcl_bamboo.mcl_log(dump(node))
end
if minetest.get_modpath("mesecons_mvps") then
if mesecon then
mcl_bamboo.mcl_log("registering mvps_dropper for bamboo:")
for x = 1, #mcl_bamboo.bamboo_index do
mesecon.register_mvps_dropper(mcl_bamboo.bamboo_index[x],dropper_call)
mcl_bamboo.mcl_log("registering: " .. mcl_bamboo.bamboo_index[x])
end
end
else
end
--]]
minetest.register_abm({
label = "Break Orphaned Bamboo",
nodenames = mcl_bamboo.bamboo_index,
interval = 1.5,
chance = 1,
action = function(pos, _)
mcl_bamboo.break_orphaned(pos)
end,
})
-- Base Aliases.
local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding"
minetest.register_alias("bamboo_block", "mcl_bamboo:bamboo_block")

View File

@ -1,4 +1,4 @@
name = mcl_bamboo
depends = mcl_core, mcl_sounds, mcl_tools
optional_depends = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, mesecons_button, mesecons_mvps
optional_depends = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, mesecons_button
author = Michieal

View File

@ -45,8 +45,8 @@ minetest.register_craft({
minetest.register_craft({
output = BAMBOO .. "_mosaic",
recipe = {
{"mcl_stairs:slab_bamboo_plank"},
{"mcl_stairs:slab_bamboo_plank"},
{"mcl_stair:slab_bamboo_plank"},
{"mcl_stair:slab_bamboo_plank"},
}
})

View File

@ -1,77 +0,0 @@
# textdomain: mcl_banners
White Banner=Estandarte Branco
White=Branco
Grey Banner=Estandarte Cinza
Grey=Cinza
Light Grey Banner=Estandarte Cinza Claro
Light Grey=Cinza Claro
Black Banner=Estandarte Preto
Black=Preto
Red Banner=Estandarte Vermelho
Red=Vermelho
Yellow Banner=Estandarte Amarelo
Yellow=Amarelo
Green Banner=Estandarte Verde
Green=Verde
Cyan Banner=Estandarte Ciano
Cyan=Ciano
Blue Banner=Estandarte Azul
Blue=Azul
Magenta Banner=Estandarte Magenta
Magenta=Magenta
Orange Banner=Estandarte Laranja
Orange=Laranja
Purple Banner=Estandarte Roxo
Violet=Violeta
Brown Banner=Estandarte Marrom
Brown=Marrom
Pink Banner=Estandarte Rosa
Pink=Rosa
Lime Banner=Estandarte Lima
Lime=Lima
Light Blue Banner=Estandarte Azul Claro
Light Blue=Azul Claro
Banners are tall colorful decorative blocks. They can be placed on the floor and at walls. Banners can be emblazoned with a variety of patterns using a lot of dye in crafting.=Estandartes são altos e coloridos blocos decorativos. Podem ser colocados no chão ou em paredes. Estandartes podem ser brasonados com uma variedade de padrões usando muitos corantes na mesa de trabalho.
Use crafting to draw a pattern on top of the banner. Emblazoned banners can be emblazoned again to combine various patterns. You can draw up to 12 layers on a banner that way. If the banner includes a gradient, only 3 layers are possible.=Use a mesa de trabalho para desenhar um padrão sob o estandarte. Estandartes brasonados podem ser brasonados novamente para combinar diversos padrões. Você pode desenhar até 12 camadas em um estandarte dessa maneira. Se o estandarte possuir gradiente, apenas 3 camadas são possíveis.
You can copy the pattern of a banner by placing two banners of the same color in the crafting grid—one needs to be emblazoned, the other one must be clean. Finally, you can use a banner on a cauldron with water to wash off its top-most layer.=Você pode copiar o padrão de um estandarte colocando dois estandartes da mesma cor na mesa de trabalho - um necessita estar brasonado, o outro, limpo. Finalmente, você pode usar um estandarte em um calderão com água para lavar fora a camada mais recente.
@1 Bordure=
@1 Bricks=
@1 Roundel=
@1 Creeper Charge=
@1 Saltire=
@1 Bordure Indented=
@1 Per Bend Inverted=
@1 Per Bend Sinister Inverted=
@1 Per Bend=
@1 Per Bend Sinister=
@1 Flower Charge=
@1 Gradient=
@1 Base Gradient=
@1 Per Fess Inverted=
@1 Per Fess=
@1 Per Pale=
@1 Per Pale Inverted=
@1 Thing Charge=
@1 Lozenge=
@1 Skull Charge=
@1 Paly=
@1 Base Dexter Canton=
@1 Base Sinister Canton=
@1 Chief Dexter Canton=
@1 Chief Sinister Canton=
@1 Cross=
@1 Base=
@1 Pale=
@1 Bend Sinister=
@1 Bend=
@1 Pale Dexter=
@1 Fess=
@1 Pale Sinister=
@1 Chief=
@1 Chevron=
@1 Chevron Inverted=
@1 Base Indented=
@1 Chief Indented=
And one additional layer=E uma camada adicional
And @1 additional layers=E @1 camada adicional
Paintable decoration=Decoração pintável

View File

@ -1,5 +0,0 @@
# textdomain: mcl_barrels
Barrel=Barril
Barrels are containers which provide 27 inventory slots.=Barris são recipientes que fornecem 27 espaços no inventário.
To access its inventory, rightclick it. When broken, the items will drop out.=Para acessar seu inventário, clique com o botão direito nele. Quando quebrado, os itens serão derrubados ao chão.
27 inventory slots=27 espaços de inventário

View File

@ -1,5 +0,0 @@
# textdomain: mcl_beacons
Beacon=Sinalizador
Beacon:=Sinalizador:
Primary Power:=Poder Primário:
Inventory:=Inventário:

View File

@ -274,11 +274,7 @@ function mcl_beds.sleep()
end
-- Always clear weather
mcl_weather.change_weather("none")
elseif mcl_beds.is_night() and weather_mod then
mcl_beds.skip_night()
mcl_beds.kick_players()
mcl_weather.change_weather("none")
elseif mcl_beds.is_night() and not weather_mod then
elseif mcl_beds.is_night() then
mcl_beds.skip_night()
mcl_beds.kick_players()
end

View File

@ -1,43 +0,0 @@
# textdomain: mcl_beds
Beds allow you to sleep at night and make the time pass faster.=Camas permitem que você durma durante a noite e faz o tempo passar mais rápido.
To use a bed, stand close to it and right-click the bed to sleep in it. Sleeping only works when the sun sets, at night or during a thunderstorm. The bed must also be clear of any danger.=Para utilizar uma cama, se aproxime dela e clique com o botão direito para dormir na cama. Dormir só funciona quando o sol se põe, a noite ou durante uma tempestade.
You have heard of other worlds in which a bed would set the start point for your next life. But this world is not one of them.=Você andou escutando de outros mundos onde uma cama colocaria o ponto de partida de sua próxima vida. Mas esse mundo não é um deles.
By using a bed, you set the starting point for your next life. If you die, you will start your next life at this bed, unless it is obstructed or destroyed.=Ao utilizar uma cama, você marca o ponto de partida de sua próxima vida. Se você morrer, voce começará sua nova vida nesta cama, a não ser que ela está obstruída ou foi destruída.
In this world, going to bed won't skip the night, but it will skip thunderstorms.=Neste mundo, ir para a cama não pulará a noite, mas pulará tempestades.
Sleeping allows you to skip the night. The night is skipped when all players in this world went to sleep. The night is skipped after sleeping for a few seconds. Thunderstorms can be skipped in the same manner.=Dormir permite que você pule a noite. A noite é pulada quando todos os jogadores deste mundo forem dormir. A noite é pulada depois de dormir por alguns segundos. Tempestades podem ser puladas da mesma maneira.
Bed=Cama
Red Bed=Cama Vermelha
Blue Bed=Cama Azul
Cyan Bed=Cama Ciana
Grey Bed=Cama Cinza
Light Grey Bed=Cama Cinza Clara
Black Bed=Cama Preta
Yellow Bed=Cama Amarela
Green Bed=Cama Verde
Magenta Bed=Cama Magenta
Orange Bed=Cama Laranja
Purple Bed=Cama Roxa
Brown Bed=Cama Marrom
Pink Bed=Cama Rosa
Lime Bed=Cama Lima
Light Blue Bed=Cama Azul Clara
White Bed=Cama Brabca
You can't sleep, the bed's too far away!=Você não pode dormir, a cama está muito longe!
This bed is already occupied!=Esta cama já está ocupada!
You have to stop moving before going to bed!=Você precisa parar de se mover antes de deitar na cama!
You can't sleep now, monsters are nearby!=Você não pode dormir agora, há monstros perto!
You can't sleep, the bed is obstructed!=Você não pode dormir, a cama está obstruída!
It's too dangerous to sleep here!=É muito perigoso dormir aqui!
New respawn position set! But you can only sleep at night or during a thunderstorm.=Nova posição de respawn marcada! Mas você só pode dormir a noite ou durante uma tempestade.
You can only sleep at night or during a thunderstorm.=Você só pode dormir a noite ou durante uma tempestade.
New respawn position set!=Nova posição de respawn marcada!
Leave bed=Sair da cama
Abort sleep=Abortar dormir
Players in bed: @1/@2=Jogadores na cama: @1/@2
Note: Night skip is disabled.=Nota: avançar a noite está desabilitado.
You're sleeping.=Voce está dormindo.
You will fall asleep when all players are in bed.=Você cairá no sono quando todos os jogadores estiverem na cama.
You will fall asleep when @1% of all players are in bed.=Você cairá no sono quando @1% de todos os jogadores estiverem na cama.
You're in bed.=Você está na cama.
Allows you to sleep=Permite que você durma
Respawn Anchor=Âncora de Respawn

View File

@ -1,2 +0,0 @@
# textdomain: mcl_bells
Bell=Sino

View File

@ -1,28 +0,0 @@
# textdomain: mcl_blackstone
Blackstone=Rocha-negra
Polished Blackstone=Rocha-negra Polida
Chiseled Polished Blackstone=Rocha-negra Polida Cinzelada
Polished Blackstone Bricks=Tijolo de Rocha-negra Polida
Basalt=Basalto
Polished Basalt=Basalto Polido
Blackstone Slab=Laje de Rocha-negra
Polished Blackstone Slab=Laje de Rocha-negra Polida
Chiseled Polished Blackstone Slab=Laje de Rocha-negra Polida Cinzelada
Polished Blackstone Brick Slab=Laje de Tijolo de Rocha-negra Polida
Blackstone Stair=Escada de Rocha-negra
Polished Blackstone Stair=Escada de Rocha-negra Polida
Chiseled Polished Blackstone Stair=Escada de Rocha-negra Polida Cinzelada
Polished Blackstone Brick Stair=Escada de Tijolo de Rocha-negra Polida
Quartz Bricks=Tijolos de Quartzo
Soul Torch=Tocha de Alma
Soul Lantern=Lanterna de Alma
Soul Soil=Solo de Alma
Eternal Soul Fire=Eterno Fogo de Alma
Gilded Blackstone=Rocha-negra Dourada
Nether Gold Ore=Minério de Ouro do Nether
Smooth Basalt=Basalto Liso
Blackstone Wall=Muro de Rocha-negra
Double Blackstone Slab=Dupla Laje de Rocha-negra
Polished Double Blackstone Slab=Dupla Laje de Rocha-negra Polida
Double Chiseled Polished Blackstone Slab=Dupla Laje de Rocha-negra Polida Cinzelada
Double Polished Blackstone Brick Slab=Dupla Laje de Tijolo de Rocha-negra Polida

View File

@ -1,8 +0,0 @@
# textdomain: mcl_blast_furnace
Inventory=Inventário
Blast Furnace=Alto-Forno
Smelts ores faster than furnace=Funde minérios mais rápido do que a fornalha
Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Utilize o livro de receitas para ver o que você pode fundir, o que você pode usar de combustível e o quanto irá queimar.
Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Utilize o alto-forno para abrir o menu. \nColoque o combustível no espaço inferior e a matéria-prima no espaço superior. \nO resultado será colocado no espaço de saída, ao lado direito.
Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=Alto-Forno derrete diversos itens, principalmente minérios e armaduras, utilizando um combustível, em algo diferente.
Active Blast Furnace=Alto-Forno Ativo

View File

@ -1,28 +0,0 @@
# textdomain: mcl_books
Book=Livro
Books are used to make bookshelves and book and quills.=Livros são utilizados para fazer prateleiras de livros e livro e pena.
“@1”=
Copy of “@1”=Copia de "@1"
Copy of Copy of “@1”=Cópia da Cópia de "@1"
Tattered Book=Livro Esfarrapado
by @1=por @1
# as in “to sign a book”
Sign=Assinar
Done=Finalizar
This item can be used to write down some notes.=Este item pode ser utilizado para escrever algumas anotações.
Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=Segure na mão e aperte o botão direito para ler e editar as anotações. Você pode editar o texto o quanto quiser. Você pode assinar o livro, o que o torna em um livro escrito em que você pode empilhar, mas não poderá ser editado mais.
A book can hold up to 4500 characters. The title length is limited to 64 characters.=Um livro pode conter até 4500 caracteres. O tamanho do título é limitado a 64 caracteres.
Enter book title:=Entre com o título do livro:
by @1=por @1
Note: The book will no longer be editable after signing=Nota: o livro não será mais editável após assinar
Sign and Close=Assinar e Fechar
Cancel=Cancelar
Nameless Book=Livro sem título
Written Book=Livro Escrito
Written books contain some text written by someone. They can be read and copied, but not edited.=Livros escritos contém textos escritos por alguém. Eles podem ser lidos e copiados, mas não editados.
Hold it in your hand, then rightclick to read the book.=Segure em sua mão e aperte o botão direito para ler o livro.
To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=Para copiar o texto de um livro escrito, coloque-o na mesa de trabalho junto de um livro e pena (ou vários deste) e copie. O livro escrito não será consumido. Copias de copias não poderão ser copiadas.
Bookshelf=Estante de Livros
Bookshelves are used for decoration.=Estante de livros são utilizadas para decoração.
Book and Quill=Livro e Pena
Write down some notes=Escreve algumas anotações

View File

@ -1,18 +0,0 @@
# textdomain: mcl_bows
Arrow=Flecha
Arrows are ammunition for bows and dispensers.=Flechas são munições para arcos e dispensores.
An arrow fired from a bow has a regular damage of 1-9. At full charge, there's a 20% chance of a critical hit dealing 10 damage instead. An arrow fired from a dispenser always deals 3 damage.=Uma flecha disparada de um arco tem um dano regular variando entre 1-9. Quando puxado o arco por completo há uma chance de 20% de acerto crítico, causando 10 de dano. Uma flecha disparada de um dispensor sempre provocará 3 de dano.
Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=Flechas poderão ficar presas em blocos sólidos e podem ser recuperadas novamente. Elas também são capazes de empurrar botões de madeira.
To use arrows as ammunition for a bow, just put them anywhere in your inventory, they will be used up automatically. To use arrows as ammunition for a dispenser, place them in the dispenser's inventory. To retrieve an arrow that sticks in a block, simply walk close to it.=Para usar flechas como munição para um arco, apenas as coloque em seu inventário, elas serão consumidas automaticamente. Para usar flechas como munição de dispensores, coloque as no inventário do dispensor. Para recuperar uma flecha presa em um bloco, simplemente se aproxime dela.
Bow=Arco
Bows are ranged weapons to shoot arrows at your foes.=Arcos são armas de longo alcance que disparam flechas em seus inimigos.
The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead.=A velocidade e o dano da flecha aumenta quanto mais você puxar o arco. O dano regular de uma flecha varia entre 1 e 9. Quando puxado no máximo, há também uma chance de 20% de causar acerto crítico, efetuando 10 de dano.
To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=Para usar o arco, você primeiro precisa possuir pelo menos uma flecha em qualquer lugar do seu inventário (a não ser no Modo Criativo). Segure o botão direito do mouse para puxar o arco, solte-o para disparar.
Bow=Arco
Ammunition=munição
Damage from bow: 1-10=Dano provocado pelo arco: 1-10
Damage from dispenser: 3=Dano provocado pelo dispensor: 3
Launches arrows=Dispara flechas
Crossbow=Besta
Crossbows are ranged weapons to shoot arrows at your foes.=Bestas são armas de longo alcance que disparam flechas em seus inimigos.
To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=Para usar a besta, vocẽ primeiro precisa possuir pelo menos uma flecha em qualquer lugar do seu inventário (a não ser no Modo Criativo). Segure o botão direito do mouse para puxar, solte-o para disparar.

View File

@ -1,10 +0,0 @@
# textdomain: mcl_brewing
Brewing Stand=Suporte de Fermentação
Inventory=Inventário
To use a brewing stand, rightclick it.=Para usar um suporte de fermentação, clique-o com o botão direito.
To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Para fermentar, você precisa de Pó de Blaze como combutível, um material de fermentação e pelo menos 1 garrafa de vidro preenchida com líquido.
Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Coloque o Pó de Blaze no espaço da esquerda, o material de fermentaçaõ no espaço do meio e 1-3 garrafas nos espaços restantes.
When you have found a good combination, the brewing will commence automatically and steam starts to appear, using up the fuel and brewing material. The potions will soon be ready.=Quando você encontrar uma boa combinação, a fermentação irá iniciar automaticamente e vapores começarão a aparecer, consumindo o combustível e o material de fermentação. A poção em breve estará pronta.
Different combinations of brewing materials and liquids will give different results. Try to experiment!=Diferentes combinações de materiais de fermentação e líquidos lhe darão diferentes resultados. Tente experimentar!
The stand allows you to brew potions!=O suporte permite que você produza poções.
Brew Potions=Produz Poções

View File

@ -56,7 +56,7 @@ for techname, fishname in pairs(fish_names) do
_doc_items_longdesc = S("This bucket is filled with water and @1.", S(fishname)),
_doc_items_usagehelp = S("Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.", S(fishname), S(fishname)),
_tt_help = S("Places a water source and a @1.", S(fishname)),
inventory_image = "mcl_buckets_" .. techname .. "_bucket.png",
inventory_image = techname .. "_bucket.png",
stack_max = 1,
groups = {bucket = 1, fish_bucket = 1},
liquids_pointable = false,

View File

@ -61,8 +61,9 @@ local function sound_take(itemname, pos)
end
local function place_liquid(pos, itemstring)
local fullness = registered_nodes[itemstring].liquid_range
sound_place(itemstring, pos)
set_node(pos, {name=itemstring})
add_node(pos, {name=itemstring, param2=fullness})
end
local function give_bucket(new_bucket, itemstack, user)

View File

@ -1,24 +0,0 @@
# textdomain: mcl_buckets
Empty Bucket=Balde Vazio
A bucket can be used to collect and release liquids.=Um balde pode ser utilizado para coletar e soltar líquidos.
Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Soque uma fonte de líquido para coletá-la. Voce pode usar um balde cheio para colocar o líquido em algum outro lugar.
Lava Bucket=Balde com Lava
A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com lava quente, contido seguramente dentro. Utilize com cautela.
Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Tome uma distância segura e coloque o balde para esvaziá-lo e criar uma fonte de lava no local. Não se queime!
Water Bucket=Balde com Água
A bucket can be used to collect and release liquids. This one is filled with water.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com água.
Place it to empty the bucket and create a water source.=Coloque-o para esvaziar o balde e criar uma fonte de água.
River Water Bucket=Balde com Água de Rio
A bucket can be used to collect and release liquids. This one is filled with river water.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com água de rio.
Place it to empty the bucket and create a river water source.=Coloque-o para esvaziar o balde e criar uma fonte de água de rio.
Collects liquids=Coleta líquidos
Places a lava source=Coloca uma fonte de lava
Places a water source=Coloca uma fonte de água
Places a river water source=Coloca uma fonte de água de rio
Cod=Bacalhau
Salmon=Salmão
Tropical Fish=Peixe Tropical
Bucket of @1=Balde com @1
This bucket is filled with water and @1.=Este balde está preenchido com água e @1
Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 fish with a bucket of water.=Coloque-o para esvaziar o balde e colocar um @1. Obtenha-o ao clicar com o botão direito em um peixe @2 com um balde com água.
Places a water source and a @1 fish.=Coloca a fonte de água e um peixe @1.

View File

@ -1,12 +0,0 @@
# textdomain: mcl_cake
Cake=Bolo
Cakes can be placed and eaten to restore hunger points. A cake has 7 slices. Each slice restores 2 hunger points and 0.4 saturation points. Cakes will be destroyed when dug or when the block below them is broken.=Bolos podem ser colocados e comidos para restaurar pontos de fome. Um bolo tem 7 pedaços. Cada pedaço restaura 2 pontos de fome e 0.4 pontos de saturação. Bolos serão destruídos quando eles, ou o bloco abaixo deles, é quebrado.
Place the cake anywhere, then rightclick it to eat a single slice. You can't eat from the cake when your hunger bar is full.=Coloque o bolo em qualquer lugar, e então aperte o botão direito nele para comer um pedaço. Você não consegue comer bolo quando sua barra de fome estiver cheia.
Cake (6 Slices Left)=Bolo (6 Pedaços Restantes)
Cake (5 Slices Left)=Bolo (5 Pedaços Restantes)
Cake (4 Slices Left)=Bolo (4 Pedaços Restantes)
Cake (3 Slices Left)=Bolo (3 Pedaços Restantes)
Cake (2 Slices Left)=Bolo (2 Pedaços Restantes)
Cake (1 Slice Left)=Bolo (1 Pedaço Restante)
With 7 tasty slices!=Com 7 deliciosos pedaços!
Hunger points: +@1 per slice=Pontos de fome: +@1 por pedaço

View File

@ -1,26 +0,0 @@
MineClone 2 Campfire API
========================
`mcl_campfires.register_campfire`
---------------------------------
Used to register campfires.
**Example Usage**
```
mcl_campfires.register_campfire("mcl_campfires:campfire", {
description = S("Campfire"),
inv_texture = "mcl_campfires_campfire_inv.png",
fire_texture = "mcl_campfires_campfire_fire.png",
lit_logs_texture = "mcl_campfires_campfire_log_lit.png",
drops = "mcl_core:charcoal_lump 2",
lightlevel = 14,
damage = 1,
})
```
**Values**
* description - human readable node name.
* inv_texture - campfire inventory texture.
* fire_texture - texture of the campfire fire.
* lit_logs_texture - texture for the logs of the lit campfire. if not changed, specify mcl_campfires_log.png.
* drops - what items drop when the campfire is mined.
* lightlevel - the level of light the campfire emits.
* damage - amount of damage the campfire deals when the player stands on it.

View File

@ -1,117 +0,0 @@
local S = minetest.get_translator(minetest.get_current_modname())
mcl_campfires = {}
function mcl_campfires.register_campfire(name, def)
-- Define Campfire
minetest.register_node(name, {
description = def.description,
_tt_help = S("Cooks food and keeps bees happy."),
_doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."),
inventory_image = def.inv_texture,
wield_image = def.inv_texture,
drawtype = "mesh",
mesh = "mcl_campfires_campfire.obj",
tiles = {{name="mcl_campfires_log.png"},},
use_texture_alpha = "clip",
groups = { handy=1, axey=1, material_wood=1, not_in_creative_inventory=1, campfire=1, },
paramtype = "light",
paramtype2 = "facedir",
on_rightclick = function (pos, node, player, itemstack, pointed_thing)
if player:get_wielded_item():get_name() == "mcl_fire:flint_and_steel" then
node.name = name.."_lit"
minetest.set_node(pos, node)
end
end,
drop = def.drops,
_mcl_silk_touch_drop = {name},
mcl_sounds.node_sound_wood_defaults(),
selection_box = {
type = 'fixed',
fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top
},
collision_box = {
type = 'fixed',
fixed = {-.5, -.5, -.5, .5, -.05, .5},
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
})
--Define Lit Campfire
minetest.register_node(name.."_lit", {
description = def.description,
_tt_help = S("Cooks food and keeps bees happy."),
_doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."),
inventory_image = def.inv_texture,
wield_image = def.inv_texture,
drawtype = "mesh",
mesh = "mcl_campfires_campfire_lit.obj",
tiles = {{
name=def.fire_texture,
animation={
type="vertical_frames",
aspect_w=16,
aspect_h=16,
length=2.0
}},
{name=def.lit_logs_texture,
animation={
type="vertical_frames",
aspect_w=16,
aspect_h=16,
length=2.0
}}
},
use_texture_alpha = "clip",
groups = { handy=1, axey=1, material_wood=1, campfire=1, lit_campfire=1 },
paramtype = "light",
paramtype2 = "facedir",
on_rightclick = function (pos, node, player, itemstack, pointed_thing)
if player:get_wielded_item():get_name():find("shovel") then
node.name = name
minetest.set_node(pos, node)
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
end
end,
drop = def.drops,
_mcl_silk_touch_drop = {name.."_lit"},
light_source = def.lightlevel,
mcl_sounds.node_sound_wood_defaults(),
selection_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top
},
collision_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.05, .5},
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
damage_per_second = def.damage,
})
end
local function burn_in_campfire(obj)
local p = obj:get_pos()
if p then
local n = minetest.find_node_near(p,0.4,{"group:lit_campfire"},true)
if n then
mcl_burning.set_on_fire(obj, 5)
end
end
end
local etime = 0
minetest.register_globalstep(function(dtime)
etime = dtime + etime
if etime < 0.5 then return end
etime = 0
for _,pl in pairs(minetest.get_connected_players()) do
burn_in_campfire(pl)
end
for _,ent in pairs(minetest.luaentities) do
if ent.is_mob then
burn_in_campfire(ent.object)
end
end
end)

View File

@ -1,9 +1,147 @@
-- ||||||||||||||||||||||||||||||||
-- ||||||||||| CAMPFIRES ||||||||||
-- ||||||||||||||||||||||||||||||||
-- TO-DO:
-- * Add Smoke Particles
-- * Add Spark Particles
-- * Add Cooking Meat
-- * Add Working Sounds
local modname = minetest.get_modpath(minetest.get_current_modname())
dofile(modname.."/api.lua") -- Load API File
dofile(modname.."/register.lua") -- Load Campfire Registration File
local S = minetest.get_translator(minetest.get_current_modname())
local campfires = {
{ name = "Campfire", lightlevel = 14, techname = "campfire", damage = 1, drops = "mcl_core:charcoal_lump 2" },
{ name = "Soul Campfire", lightlevel = 10, techname = "soul_campfire", damage = 2, drops = "mcl_blackstone:soul_soil" },
}
for _, campfire in pairs(campfires) do
-- Define Campfire
minetest.register_node("mcl_campfires:" .. campfire.techname, {
description = S(campfire.name),
_tt_help = S("Cooks food and keeps bees happy."),
_doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."),
inventory_image = "mcl_campfires_" .. campfire.techname .. "_inv.png",
drawtype = "mesh",
mesh = "mcl_campfires_campfire.obj",
tiles = {{name="mcl_campfires_log.png"},},
use_texture_alpha = "clip",
groups = { handy=1, axey=1, material_wood=1, not_in_creative_inventory=1, campfire=1, },
paramtype = "light",
paramtype2 = "facedir",
on_rightclick = function (pos, node, player, itemstack, pointed_thing)
if player:get_wielded_item():get_name() == "mcl_fire:flint_and_steel" then
node.name = "mcl_campfires:" .. campfire.techname .. "_lit"
minetest.set_node(pos, node)
end
end,
drop = campfire.drops,
_mcl_silk_touch_drop = {"mcl_campfires:" .. campfire.techname},
mcl_sounds.node_sound_wood_defaults(),
selection_box = {
type = 'fixed',
fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top
},
collision_box = {
type = 'fixed',
fixed = {-.5, -.5, -.5, .5, -.05, .5},
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
})
--Define Lit Campfire
minetest.register_node("mcl_campfires:" .. campfire.techname .. "_lit", {
description = S(campfire.name),
_tt_help = S("Cooks food and keeps bees happy."),
_doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."),
inventory_image = "mcl_campfires_" .. campfire.techname .. "_inv.png",
drawtype = "mesh",
mesh = "mcl_campfires_campfire_lit.obj",
tiles = {{
name="mcl_campfires_" .. campfire.techname .. "_fire.png",
animation={
type="vertical_frames",
aspect_w=16,
aspect_h=16,
length=2.0
}},
{name="mcl_campfires_" .. campfire.techname .. "_log_lit.png",
animation={
type="vertical_frames",
aspect_w=16,
aspect_h=16,
length=2.0
}}
},
use_texture_alpha = "clip",
groups = { handy=1, axey=1, material_wood=1, campfire=1, lit_campfire=1 },
paramtype = "light",
paramtype2 = "facedir",
on_rightclick = function (pos, node, player, itemstack, pointed_thing)
if player:get_wielded_item():get_name():find("shovel") then
node.name = "mcl_campfires:" .. campfire.techname
minetest.set_node(pos, node)
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
end
end,
drop = campfire.drops,
_mcl_silk_touch_drop = {"mcl_campfires:" .. campfire.techname .. "_lit"},
light_source = campfire.lightlevel,
mcl_sounds.node_sound_wood_defaults(),
selection_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top
},
collision_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.05, .5},
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
damage_per_second = campfire.damage,
})
end
minetest.register_craft({
output = "mcl_campfires:campfire_lit",
recipe = {
{ "", "mcl_core:stick", "" },
{ "mcl_core:stick", "group:coal", "mcl_core:stick" },
{ "group:tree", "group:tree", "group:tree" },
}
})
minetest.register_craft({
output = "mcl_campfires:soul_campfire_lit",
recipe = {
{ "", "mcl_core:stick", "" },
{ "mcl_core:stick", "group:soul_block", "mcl_core:stick" },
{ "group:tree", "group:tree", "group:tree" },
}
})
local function burn_in_campfire(obj)
local p = obj:get_pos()
if p then
local n = minetest.find_node_near(p,0.4,{"group:lit_campfire"},true)
if n then
mcl_burning.set_on_fire(obj, 5)
end
end
end
local etime = 0
minetest.register_globalstep(function(dtime)
etime = dtime + etime
if etime < 0.5 then return end
etime = 0
for _,pl in pairs(minetest.get_connected_players()) do
burn_in_campfire(pl)
end
for _,ent in pairs(minetest.luaentities) do
if ent.is_mob then
burn_in_campfire(ent.object)
end
end
end)

View File

@ -1,5 +0,0 @@
# textdomain: mcl_campfires
Campfire=Fogueira
Soul Campfire=Fogueira de Almas
Cooks food and keeps bees happy.=Cozinhe comida e mantenha as abelhas felizes.
Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Fogueiras possuem multiplos usos, incluindo manter abelhas felizes, cozinhar carnes cruas e peixes e como uma armadilha.

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