Merge pull request 'Merge with master.' (#1) from MineClone2/MineClone2:master into master

Reviewed-on: https://git.minetest.land/ChrisPHP/MineClone2/pulls/1
This commit is contained in:
ChrisPHP 2022-08-13 10:14:27 +00:00
commit a356be5f76
41 changed files with 644 additions and 217 deletions

View File

@ -31,6 +31,7 @@
* chmodsayshello * chmodsayshello
* PrarieWind * PrarieWind
* RandomLegoBrick * RandomLegoBrick
* SumianVoice
## Contributors ## Contributors
* Laurent Rocher * Laurent Rocher
@ -79,6 +80,8 @@
* MrRar * MrRar
* Lazerbeak12345 * Lazerbeak12345
* mrminer * mrminer
* Thunder1035
* opfromthestart
## MineClone5 ## MineClone5
* kay27 * kay27

View File

@ -2,7 +2,7 @@
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB. Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.78 (in development) Version: 0.79 (in development)
### Gameplay ### Gameplay
You start in a randomly-generated world made entirely of cubes. You can explore You start in a randomly-generated world made entirely of cubes. You can explore

View File

@ -24,6 +24,10 @@ local function is_ice(pos)
return is_group(pos, "ice") return is_group(pos, "ice")
end end
local function is_fire(pos)
return is_group(pos, "set_on_fire")
end
local function get_sign(i) local function get_sign(i)
if i == 0 then if i == 0 then
return 0 return 0
@ -218,6 +222,10 @@ function boat.on_step(self, dtime, moveresult)
on_water = false on_water = false
if not in_water and is_ice(waterp) then if not in_water and is_ice(waterp) then
on_ice = true on_ice = true
elseif is_fire({x=p.x, y=p.y-boat_y_offset, z=p.z}) then
boat.on_death(self, nil)
self.object:remove()
return
else else
v_slowdown = 0.04 v_slowdown = 0.04
v_factor = 0.5 v_factor = 0.5

View File

@ -847,8 +847,7 @@ minetest.register_entity(":__builtin:item", {
elseif self._flowing == true and not is_in_water and not is_floating then elseif self._flowing == true and not is_in_water and not is_floating then
-- Disable flowing physics if not on/in flowing liquid -- Disable flowing physics if not on/in flowing liquid
self._flowing = false self._flowing = false
local pos = self.object:get_pos() disable_physics(self.object, self, true)
disable_physics(self.object, self, false, false)
return return
end end

View File

@ -92,7 +92,8 @@ local function check_perch(self,dtime)
local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name
local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name
local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name
if n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0 then if ( n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0) and
not minetest.is_creative_enabled(p:get_player_name()) then
o:set_detach() o:set_detach()
self.detach_timer = 0 self.detach_timer = 0
return return
@ -118,7 +119,7 @@ end
mcl_mobs:register_mob("mobs_mc:parrot", { mcl_mobs:register_mob("mobs_mc:parrot", {
description = S("Parrot"), description = S("Parrot"),
type = "npc", type = "passive",
spawn_class = "passive", spawn_class = "passive",
pathfinding = 1, pathfinding = 1,
hp_min = 6, hp_min = 6,

View File

@ -816,7 +816,7 @@ local function show_trade_formspec(playername, trader, tradenum)
.."listring[current_player;main]" .."listring[current_player;main]"
.."listring["..tradeinv..";input]" .."listring["..tradeinv..";input]"
.."listring[current_player;main]" .."listring[current_player;main]"
minetest.sound_play("mobs_mc_villager_trade", {to_player = playername}, true) minetest.sound_play("mobs_mc_villager_trade", {to_player = playername,object=trader.object}, true)
minetest.show_formspec(playername, tradeinv_name, formspec) minetest.show_formspec(playername, tradeinv_name, formspec)
end end
@ -878,13 +878,13 @@ local function update_offer(inv, player, sound)
(trade.locked == false)) then (trade.locked == false)) then
inv:set_stack("output", 1, inv:get_stack("offered", 1)) inv:set_stack("output", 1, inv:get_stack("offered", 1))
if sound then if sound then
minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true)
end end
return true return true
else else
inv:set_stack("output", 1, ItemStack("")) inv:set_stack("output", 1, ItemStack(""))
if sound then if sound then
minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true)
end end
return false return false
end end
@ -1084,7 +1084,8 @@ local trade_inventory = {
if not wanted2:is_empty() then if not wanted2:is_empty() then
inv:remove_item("input", inv:get_stack("wanted", 2)) inv:remove_item("input", inv:get_stack("wanted", 2))
end end
minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name()}, true) local trader = player_trading_with[name]
minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name(),object=trader.object}, true)
end end
update_offer(inv, player, true) update_offer(inv, player, true)
end, end,
@ -1194,10 +1195,11 @@ local trade_inventory = {
elseif listname == "input" then elseif listname == "input" then
update_offer(inv, player, false) update_offer(inv, player, false)
end end
local trader = player_trading_with[name]
if accept then if accept then
minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true)
else else
minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true)
end end
end, end,
} }

View File

@ -2,6 +2,7 @@ local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_pa
local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900 local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900
local get_connected_players = minetest.get_connected_players local get_connected_players = minetest.get_connected_players
local mgname = minetest.get_mapgen_setting("mg_name")
mcl_weather.rain = { mcl_weather.rain = {
-- max rain particles created at time -- max rain particles created at time
@ -91,7 +92,7 @@ end
function mcl_weather.rain.add_player(player) function mcl_weather.rain.add_player(player)
if mcl_weather.players[player:get_player_name()] == nil then if mcl_weather.players[player:get_player_name()] == nil then
local player_meta = {} local player_meta = {}
player_meta.origin_sky = {player:get_sky()} player_meta.origin_sky = {player:get_sky(true)}
mcl_weather.players[player:get_player_name()] = player_meta mcl_weather.players[player:get_player_name()] = player_meta
update_sound[player:get_player_name()]=true update_sound[player:get_player_name()]=true
end end

View File

@ -246,7 +246,7 @@ mcl_weather.skycolor = {
get_current_bg_color = function() get_current_bg_color = function()
local players = mcl_weather.skycolor.utils.get_players(nil) local players = mcl_weather.skycolor.utils.get_players(nil)
if players[1] then if players[1] then
return players[1]:get_sky() return players[1]:get_sky(true).sky_color
end end
return nil return nil
end end
@ -276,6 +276,11 @@ minetest.register_globalstep(function(dtime)
end) end)
local function initsky(player) local function initsky(player)
if player.set_lighting then
player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("mcl_default_shadow_intensity") or 0.33) } })
end
if (mcl_weather.skycolor.active) then if (mcl_weather.skycolor.active) then
mcl_weather.skycolor.force_update = true mcl_weather.skycolor.force_update = true
end end

View File

@ -106,7 +106,7 @@ local function info()
end end
after(refresh_interval, info) after(refresh_interval, info)
end end
info() minetest.after(0,info)
minetest.register_on_leaveplayer(function(p) minetest.register_on_leaveplayer(function(p)
local name = p:get_player_name() local name = p:get_player_name()

View File

@ -261,7 +261,7 @@ local dispenserdef = {
local item_entity = minetest.add_item(droppos, dropitem) local item_entity = minetest.add_item(droppos, dropitem)
local drop_vel = vector.subtract(droppos, pos) local drop_vel = vector.subtract(droppos, pos)
local speed = 3 local speed = 3
item_entity:set_velocity(drop_vel * speed) item_entity:set_velocity(vector.multiply(drop_vel,speed))
end end
else else
stack:take_item() stack:take_item()
@ -278,7 +278,7 @@ local dispenserdef = {
local item_entity = minetest.add_item(droppos, dropitem) local item_entity = minetest.add_item(droppos, dropitem)
local drop_vel = vector.subtract(droppos, pos) local drop_vel = vector.subtract(droppos, pos)
local speed = 3 local speed = 3
item_entity:set_velocity(drop_vel * speed) item_entity:set_velocity(vector.multiply(drop_vel,speed))
stack:take_item() stack:take_item()
inv:set_stack("main", stack_id, stack) inv:set_stack("main", stack_id, stack)
end end

View File

@ -143,7 +143,7 @@ local dropperdef = {
local item_entity = minetest.add_item(droppos, dropitem) local item_entity = minetest.add_item(droppos, dropitem)
local drop_vel = vector.subtract(droppos, pos) local drop_vel = vector.subtract(droppos, pos)
local speed = 3 local speed = 3
item_entity:set_velocity(drop_vel * speed) item_entity:set_velocity(vector.multiply(drop_vel,speed))
stack:take_item() stack:take_item()
inv:set_stack("main", stack_id, stack) inv:set_stack("main", stack_id, stack)
end end

View File

@ -33,7 +33,7 @@ mcl_damage.register_modifier(function(obj, damage, reason)
local itemname = itemstack:get_name() local itemname = itemstack:get_name()
local enchantments = mcl_enchanting.get_enchantments(itemstack) local enchantments = mcl_enchanting.get_enchantments(itemstack)
if not flags.bypasses_armor then if not flags.bypasses_armor and minetest.get_item_group(itemname, "non_combat_armor") == 0 then
points = points + minetest.get_item_group(itemname, "mcl_armor_points") points = points + minetest.get_item_group(itemname, "mcl_armor_points")
toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness")

View File

@ -344,9 +344,6 @@ minetest.register_node("mcl_beacons:beacon", {
mesecon.register_mvps_stopper("mcl_beacons:beacon") mesecon.register_mvps_stopper("mcl_beacons:beacon")
mcl_wip.register_wip_item("mcl_beacons:beacon") mcl_wip.register_wip_item("mcl_beacons:beacon")
beacon_blocklist = {"mcl_core:diamondblock","mcl_core:ironblock","mcl_core:goldblock","mcl_core:emeraldblock","mcl_nether:netheriteblock"}--this is supposed to be a global, don't change that!
beacon_fuellist ={"mcl_core:diamond","mcl_core:emerald","mcl_core:iron_ingot","mcl_core:gold_ingot","mcl_nether:netherite_ingot"}
function register_beaconblock (itemstring)--API function for other mods function register_beaconblock (itemstring)--API function for other mods
table.insert(beacon_blocklist, itemstring) table.insert(beacon_blocklist, itemstring)
end end

View File

@ -1,2 +1,3 @@
name = mcl_beacons
author=chmodsayshello author=chmodsayshello
depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether

View File

@ -49,6 +49,7 @@ minetest.register_node("mcl_core:water_flowing", {
liquid_alternative_source = "mcl_core:water_source", liquid_alternative_source = "mcl_core:water_source",
liquid_viscosity = WATER_VISC, liquid_viscosity = WATER_VISC,
liquid_range = 7, liquid_range = 7,
waving = 3,
post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C},
groups = { water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1, dig_by_piston=1}, groups = { water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1, dig_by_piston=1},
_mcl_blast_resistance = 100, _mcl_blast_resistance = 100,
@ -67,6 +68,7 @@ S("• When flowing water touches flowing lava either from above or horizontally
S("• When water is directly below lava, the water turns into stone."), S("• When water is directly below lava, the water turns into stone."),
_doc_items_hidden = false, _doc_items_hidden = false,
drawtype = "liquid", drawtype = "liquid",
waving = 3,
tiles = { tiles = {
{name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}}
}, },

View File

@ -1,5 +1,6 @@
local S = minetest.get_translator(minetest.get_current_modname()) local S = minetest.get_translator(minetest.get_current_modname())
local minetest = minetest
local mod_doc = minetest.get_modpath("doc") local mod_doc = minetest.get_modpath("doc")
local mod_screwdriver = minetest.get_modpath("screwdriver") local mod_screwdriver = minetest.get_modpath("screwdriver")
@ -8,68 +9,93 @@ if minetest.get_modpath("mcl_armor") then
equip_armor = mcl_armor.equip_on_use equip_armor = mcl_armor.equip_on_use
end end
-- Heads system mcl_heads = {}
local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) -- rotations of head nodes within a quadrant (0° ≤ θ ≤ 90°)
local on_rotate_floor, on_rotate_wall mcl_heads.FLOOR_DEGREES = { [0]='', '22_5', '45', '67_5', }
if mod_screwdriver then
on_rotate_floor = function(pos, node, user, mode, new_param2) -- box of head nodes
mcl_heads.FLOOR_BOX = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }
-- floor head node nodedef template ------------------------------------------------------------------------------------
--- node definition template for floor mod heads
mcl_heads.deftemplate_floor = {
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = mcl_heads.FLOOR_BOX,
},
groups = {
handy = 1,
armor = 1,
armor_head = 1,
non_combat_armor = 1,
non_combat_armor_head = 1,
head = 1,
deco_block = 1,
dig_by_piston = 1,
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "facedir",
stack_max = 64,
sunlight_propagates = true,
sounds = mcl_sounds.node_sound_defaults{
footstep = {name="default_hard_footstep", gain=0.3},
},
is_ground_content = false,
_mcl_armor_element = "head",
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
on_secondary_use = equip_armor,
}
mcl_heads.deftemplate_floor_angled = {
drawtype = "mesh",
selection_box = {
type = "fixed",
fixed = mcl_heads.FLOOR_BOX,
},
collision_box = {
type = "fixed",
fixed = mcl_heads.FLOOR_BOX,
},
groups = {
handy = 1,
head = 1,
deco_block = 1,
dig_by_piston = 1,
not_in_creative_inventory = 1,
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "facedir",
stack_max = 64,
sunlight_propagates = true,
sounds = mcl_sounds.node_sound_defaults{
footstep = {name="default_hard_footstep", gain=0.3},
},
is_ground_content = false,
_doc_items_create_entry = false,
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
}
function mcl_heads.deftemplate_floor.on_rotate(pos, node, user, mode, new_param2)
if mode == screwdriver.ROTATE_AXIS then if mode == screwdriver.ROTATE_AXIS then
node.name = node.name .. "_wall" node.name = node.name .. "_wall"
node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2))
minetest.set_node(pos, node) minetest.set_node(pos, node)
return true return true
end end
end end
on_rotate_wall = function(pos, node, user, mode, new_param2)
if mode == screwdriver.ROTATE_AXIS then
node.name = string.sub(node.name, 1, string.len(node.name)-5)
node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2))
minetest.set_node(pos, node)
return true
end
end
end
minetest.register_node("mcl_heads:"..name, { function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing)
description = desc,
_doc_items_longdesc = longdesc,
drawtype = "nodebox",
is_ground_content = false,
node_box = {
type = "fixed",
fixed = {
{ -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
},
},
groups = {handy = 1, armor = 1, armor_head = 1, non_combat_armor = 1, non_combat_armor_head = 1, head = 1, deco_block = 1, dig_by_piston = 1},
-- The head textures are based off the textures of an actual mob.
tiles = {
-- Note: bottom texture is overlaid over top texture to get rid of possible transparency.
-- This is required for skeleton skull and wither skeleton skull.
"[combine:16x16:-4,4="..texture, -- top
"([combine:16x16:-4,4="..texture..")^([combine:16x16:-12,4="..texture..")", -- bottom
"[combine:16x16:-12,0="..texture, -- left
"[combine:16x16:4,0="..texture, -- right
"[combine:16x16:-20,0="..texture, -- back
"[combine:16x16:-4,0="..texture, -- front
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
stack_max = 64,
paramtype2 = "facedir",
sunlight_propagates = true,
walkable = true,
selection_box = {
type = "fixed",
fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
},
sounds = mcl_sounds.node_sound_defaults({
footstep = {name="default_hard_footstep", gain=0.3}
}),
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
-- no interaction possible with entities, for now.
return itemstack return itemstack
end end
@ -78,7 +104,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then return itemstack end if not def then return itemstack end
-- Call on_rightclick if the pointed node defines it -- Allow pointed node's on_rightclick callback to override place.
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack
@ -86,81 +112,186 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor)
end end
local above = pointed_thing.above local above = pointed_thing.above
local diff = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
local wdir = minetest.dir_to_wallmounted(diff) local wdir = minetest.dir_to_wallmounted(dir)
local itemstring = itemstack:get_name() local itemstring = itemstack:get_name()
local fakestack = ItemStack(itemstack) local placestack = ItemStack(itemstack)
--local idef = fakestack:get_definition()
local retval -- place wall head node (elsewhere)
if wdir == 0 or wdir == 1 then if wdir ~= 0 and wdir ~= 1 then
return minetest.item_place(itemstack, placer, pointed_thing) placestack:set_name(itemstring .."_wall")
itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir)
-- place floor head node (floor and ceiling)
else else
retval = fakestack:set_name("mcl_heads:"..name.."_wall") local fdir = minetest.dir_to_facedir(dir)
-- determine the head node rotation based on player's yaw (in cw direction from North/Z+)
local yaw = placer:get_look_horizontal()
yaw = wdir == 1 and math.pi*2 - yaw or yaw
local rotation_level = math.min(math.max(math.round((yaw / (math.pi*2)) * 16), 0), 15)
placestack:set_name(itemstring ..mcl_heads.FLOOR_DEGREES[rotation_level % 4])
-- determine the head node face direction based on rotation level
fdir = math.floor(rotation_level / 4) + (wdir == 1 and 0 or 20)
itemstack = minetest.item_place(placestack, placer, pointed_thing, fdir)
end end
if not retval then
return itemstack -- restore item from angled and wall head nodes
end
itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir)
itemstack:set_name(itemstring) itemstack:set_name(itemstring)
return itemstack return itemstack
end, end
on_secondary_use = equip_armor,
on_rotate = on_rotate_floor, -- wall head node nodedef template -------------------------------------------------------------------------------------
_mcl_armor_mob_range_mob = rangemob, --- node definition template for wall mod heads
_mcl_armor_mob_range_factor = rangefactor, mcl_heads.deftemplate_wall = {
_mcl_armor_element = "head",
_mcl_armor_texture = "mcl_heads_" .. name .. ".png",
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
})
minetest.register_node("mcl_heads:"..name.."_wall", {
_doc_items_create_entry = false,
drawtype = "nodebox", drawtype = "nodebox",
is_ground_content = false,
node_box = { node_box = {
type = "wallmounted", type = "wallmounted",
wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, },
wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, },
}, },
groups = {handy=1, head=1, deco_block=1, dig_by_piston=1, not_in_creative_inventory=1}, groups = {
-- The head textures are based off the textures of an actual mob. handy = 1,
tiles = { head = 1,
{ name = "[combine:16x16:-4,-4="..texture, align_style = "world" }, -- front deco_block = 1,
{ name = "[combine:16x16:-20,-4="..texture, align_style = "world" }, -- back dig_by_piston = 1,
{ name = "[combine:16x16:-8,-4="..texture, align_style = "world" }, -- left not_in_creative_inventory = 1,
{ name = "[combine:16x16:0,-4="..texture, align_style = "world" }, -- right
{ name = "([combine:16x16:-4,0="..texture..")^[transformR180", align_style = "node" }, -- top
{ name = "([combine:16x16:-4,8="..texture..")^([combine:16x16:-12,8="..texture..")", align_style = "node" }, -- bottom
}, },
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light", paramtype = "light",
stack_max = 64,
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
stack_max = 64,
sunlight_propagates = true, sunlight_propagates = true,
walkable = true, sounds = mcl_sounds.node_sound_defaults{
sounds = mcl_sounds.node_sound_defaults({ footstep = {name="default_hard_footstep", gain=0.3},
footstep = {name="default_hard_footstep", gain=0.3} },
}), is_ground_content = false,
drop = "mcl_heads:"..name,
on_rotate = on_rotate_wall, _doc_items_create_entry = false,
_mcl_blast_resistance = 1, _mcl_blast_resistance = 1,
_mcl_hardness = 1, _mcl_hardness = 1,
}) }
if mod_doc then function mcl_heads.deftemplate_wall.on_rotate(pos, node, user, mode, new_param2)
doc.add_entry_alias("nodes", "mcl_heads:" .. name, "nodes", "mcl_heads:" .. name .. "_wall") if mode == screwdriver.ROTATE_AXIS then
node.name = string.sub(node.name, 1, string.len(node.name)-5)
node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2))
minetest.set_node(pos, node)
return true
end end
end end
-- Add heads -- API functions -------------------------------------------------------------------------------------------------------
addhead("zombie", "mcl_heads_zombie_node.png", S("Zombie Head"), S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), "mobs_mc:zombie", 0.5)
addhead("creeper", "mcl_heads_creeper_node.png", S("Creeper Head"), S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), "mobs_mc:creeper", 0.5) --- @class HeadDef
--- @field name string identifier for node
--- @field texture string armor texture for node
--- @field description string translated description
--- @field longdesc string translated doc description
--- @field range_mob string name of mob affected by range reduction
--- @field range_factor number factor of range reduction
--- registers a head
--- @param head_def HeadDef head node definition
function mcl_heads.register_head(head_def)
local name = "mcl_heads:" ..head_def.name
-- register the floor head node
minetest.register_node(name, table.update(table.copy(mcl_heads.deftemplate_floor), {
description = head_def.description,
_doc_items_longdesc = head_def.longdesc,
-- The head textures are based off the textures of an actual mob.
tiles = {
-- Note: bottom texture is overlaid over top texture to get rid of possible transparency.
-- This is required for skeleton skull and wither skeleton skull.
-- Note: -x coords go right per-pixel, -y coords go down per-pixel
"[combine:16x16:-36,4=" ..head_def.texture, -- top
"([combine:16x16:-36,4=" ..head_def.texture..")^([combine:16x16:-44,4="..head_def.texture..")", -- bottom
"[combine:16x16:-28,0=" ..head_def.texture, -- left
"[combine:16x16:-44,0=" ..head_def.texture, -- right
"[combine:16x16:-52,0=" ..head_def.texture, -- back
"[combine:16x16:-36,0=" ..head_def.texture, -- front
},
_mcl_armor_mob_range_mob = head_def.range_mob,
_mcl_armor_mob_range_factor = head_def.range_factor,
_mcl_armor_texture = head_def.texture
}))
-- register the angled floor head nodes
for i, d in ipairs(mcl_heads.FLOOR_DEGREES) do
minetest.register_node(name ..d, table.update(table.copy(mcl_heads.deftemplate_floor_angled), {
mesh = "mcl_heads_floor" ..d ..".obj",
tiles = { head_def.texture },
drop = name,
}))
end
-- register the wall head node
minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), {
-- The head textures are based off the textures of an actual mob.
-- Note: -x coords go right per-pixel, -y coords go down per-pixel
tiles = {
{ name = "[combine:16x16:-36,-4=" ..head_def.texture, align_style = "world" }, -- front
{ name = "[combine:16x16:-52,-4="..head_def.texture, align_style = "world" }, -- back
{ name = "[combine:16x16:-40,-4=" ..head_def.texture, align_style = "world" }, -- right
{ name = "[combine:16x16:-32,-4=" ..head_def.texture, align_style = "world" }, -- left
{ name = "([combine:16x16:-36,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top
-- Note: bottom texture is overlaid over top texture to get rid of possible transparency.
-- This is required for skeleton skull and wither skeleton skull.
{ name = "([combine:16x16:-36,0=" ..head_def.texture ..")^([combine:16x16:-44,8=" ..head_def.texture..")", align_style = "node" }, -- bottom
},
drop = name,
}))
end
-- initial heads -------------------------------------------------------------------------------------------------------
mcl_heads.register_head{
name = "zombie",
texture = "mcl_heads_zombie.png",
description = S("Zombie Head"),
longdesc = S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."),
range_mob = "mobs_mc:zombie",
range_factor = 0.5,
}
mcl_heads.register_head{
name = "creeper",
texture = "mcl_heads_creeper.png",
description = S("Creeper Head"),
longdesc = S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."),
range_mob = "mobs_mc:creeper",
range_factor = 0.5,
}
-- Original Minecraft name: “Head” -- Original Minecraft name: “Head”
addhead("steve", "mcl_heads_steve_node.png", S("Human Head"), S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.")) mcl_heads.register_head{
addhead("skeleton", "mcl_heads_skeleton_node.png", S("Skeleton Skull"), S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), "mobs_mc:skeleton", 0.5) name = "steve",
addhead("wither_skeleton", "mcl_heads_wither_skeleton_node.png", S("Wither Skeleton Skull"), S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.")) texture = "mcl_heads_steve.png",
description = S("Human Head"),
longdesc = S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection."),
}
mcl_heads.register_head{
name = "skeleton",
texture = "mcl_heads_skeleton.png",
description = S("Skeleton Skull"),
longdesc = S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."),
range_mob = "mobs_mc:skeleton",
range_factor = 0.5,
}
mcl_heads.register_head{
name = "wither_skeleton",
texture = "mcl_heads_wither_skeleton.png",
description = S("Wither Skeleton Skull"),
longdesc = S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection."),
}

View File

@ -0,0 +1,42 @@
# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend'
# www.blender.org
mtllib mcl_heads_floor22_5.mtl
o Cube.001
v -0.326641 -0.500000 0.135299
v -0.326641 0.000000 0.135299
v -0.135299 -0.500000 -0.326641
v -0.135299 0.000000 -0.326641
v 0.135299 -0.500000 0.326641
v 0.135299 0.000000 0.326641
v 0.326641 -0.500000 -0.135299
v 0.326641 0.000000 -0.135299
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.750000 0.750000
vt 0.750000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.500000 0.750000
vt 0.500000 0.500000
vt 1.000000 0.500000
vt 1.000000 0.750000
vt 0.875000 0.750000
vt 0.875000 1.000000
vt 0.750000 1.000000
vt 0.750000 0.750000
vt 0.750000 1.000000
vt 0.625000 1.000000
vn -0.9239 0.0000 -0.3827
vn 0.3827 0.0000 -0.9239
vn 0.9239 0.0000 0.3827
vn -0.3827 0.0000 0.9239
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material.001
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/9/4 6/10/4 2/2/4 1/1/4
f 3/11/5 7/12/5 5/13/5 1/14/5
f 8/5/6 4/3/6 2/15/6 6/16/6

View File

@ -0,0 +1,42 @@
# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend'
# www.blender.org
mtllib mcl_heads_floor45.mtl
o Cube.002
v -0.353553 -0.500000 0.000000
v -0.353553 0.000000 0.000000
v 0.000000 -0.500000 -0.353553
v 0.000000 0.000000 -0.353553
v 0.000000 -0.500000 0.353553
v 0.000000 0.000000 0.353553
v 0.353553 -0.500000 0.000000
v 0.353553 0.000000 0.000000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.750000 0.750000
vt 0.750000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.500000 0.750000
vt 0.500000 0.500000
vt 1.000000 0.500000
vt 1.000000 0.750000
vt 0.875000 0.750000
vt 0.875000 1.000000
vt 0.750000 1.000000
vt 0.750000 0.750000
vt 0.750000 1.000000
vt 0.625000 1.000000
vn -0.7071 0.0000 -0.7071
vn 0.7071 0.0000 -0.7071
vn 0.7071 0.0000 0.7071
vn -0.7071 0.0000 0.7071
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material.002
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/9/4 6/10/4 2/2/4 1/1/4
f 3/11/5 7/12/5 5/13/5 1/14/5
f 8/5/6 4/3/6 2/15/6 6/16/6

View File

@ -0,0 +1,42 @@
# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend'
# www.blender.org
mtllib mcl_heads_floor67_5.mtl
o Cube.003
v -0.326641 -0.500000 -0.135299
v -0.326641 0.000000 -0.135299
v 0.135299 -0.500000 -0.326641
v 0.135299 0.000000 -0.326641
v -0.135299 -0.500000 0.326641
v -0.135299 0.000000 0.326641
v 0.326641 -0.500000 0.135299
v 0.326641 0.000000 0.135299
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.750000 0.750000
vt 0.750000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.500000 0.750000
vt 0.500000 0.500000
vt 1.000000 0.500000
vt 1.000000 0.750000
vt 0.875000 0.750000
vt 0.875000 1.000000
vt 0.750000 1.000000
vt 0.750000 0.750000
vt 0.750000 1.000000
vt 0.625000 1.000000
vn -0.3827 0.0000 -0.9239
vn 0.9239 0.0000 -0.3827
vn 0.3827 0.0000 0.9239
vn -0.9239 0.0000 0.3827
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material.003
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/9/4 6/10/4 2/2/4 1/1/4
f 3/11/5 7/12/5 5/13/5 1/14/5
f 8/5/6 4/3/6 2/15/6 6/16/6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 B

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -5,6 +5,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
local source = table.copy(minetest.registered_nodes["mcl_core:water_source"]) local source = table.copy(minetest.registered_nodes["mcl_core:water_source"])
source.description = S("River Water Source") source.description = S("River Water Source")
source.liquid_range = 2 source.liquid_range = 2
source.waving = 3
source.liquid_alternative_flowing = "mclx_core:river_water_flowing" source.liquid_alternative_flowing = "mclx_core:river_water_flowing"
source.liquid_alternative_source = "mclx_core:river_water_source" source.liquid_alternative_source = "mclx_core:river_water_source"
source.liquid_renewable = false source.liquid_renewable = false
@ -28,6 +29,7 @@ source.special_tiles = {
local flowing = table.copy(minetest.registered_nodes["mcl_core:water_flowing"]) local flowing = table.copy(minetest.registered_nodes["mcl_core:water_flowing"])
flowing.description = S("Flowing River Water") flowing.description = S("Flowing River Water")
flowing.liquid_range = 2 flowing.liquid_range = 2
flowing.waving = 3
flowing.liquid_alternative_flowing = "mclx_core:river_water_flowing" flowing.liquid_alternative_flowing = "mclx_core:river_water_flowing"
flowing.liquid_alternative_source = "mclx_core:river_water_source" flowing.liquid_alternative_source = "mclx_core:river_water_source"
flowing.liquid_renewable = false flowing.liquid_renewable = false

View File

@ -1,5 +1,12 @@
mcl_structures.registered_structures = {} mcl_structures.registered_structures = {}
local disabled_structures = minetest.settings:get("mcl_disabled_structures")
if disabled_structures then disabled_structures = disabled_structures:split(",")
else disabled_structures = {} end
function mcl_structures.is_disabled(structname)
if table.indexof(disabled_structures,structname) ~= -1 then return true end
end
function mcl_structures.fill_chests(p1,p2,loot,pr) function mcl_structures.fill_chests(p1,p2,loot,pr)
for it,lt in pairs(loot) do for it,lt in pairs(loot) do
@ -38,6 +45,88 @@ function mcl_structures.find_highest_y(pp)
return y return y
end end
local function smooth_cube(nn,pos,plane,amnt)
local r = {}
local amnt = amnt or 9
table.sort(nn,function(a, b)
if false or plane then
return vector.distance(vector.new(pos.x,0,pos.z), vector.new(a.x,0,a.z)) < vector.distance(vector.new(pos.x,0,pos.z), vector.new(b.x,0,b.z))
else
return vector.distance(pos, a) < vector.distance(pos, b)
end
end)
for i=1,math.max(1,#nn-amnt) do table.insert(r,nn[i]) end
return r
end
local function find_ground(pos,nn,gn)
local r = 0
for _,v in pairs(nn) do
local p=vector.new(v)
repeat
local n = minetest.get_node(p).name
p = vector.offset(p,0,-1,0)
until not n or n == "mcl_core:bedrock" or n == "ignore" or n == gn
--minetest.log(tostring(pos.y - p.y))
if pos.y - p.y > r then r = pos.y - p.y end
end
return r
end
local function get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone)
local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves","group:plant","grass_block","group:dirt"}
local depth = find_ground(pos,minetest.find_nodes_in_area(ground_p1,ground_p2,replace),node_stone)
local nn = smooth_cube(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-depth,0),replace),vector.offset(pos,0,-depth,0),true,sidelen * 64)
local stone = {}
local filler = {}
local top = {}
local dust = {}
for l,v in pairs(nn) do
if v.y == ground_p1.y - 1 then
table.insert(filler,v)
table.insert(top,vector.offset(v,0,1,0))
table.insert(dust,vector.offset(v,0,2,0))
elseif v.y < ground_p1.y -1 and v.y > ground_p2.y -4 then table.insert(filler,v)
elseif v.y < ground_p2.y - 3 and v.y > ground_p2.y -5 then
if math.random(3) == 1 then
table.insert(filler,v)
else
table.insert(stone,v)
end
else
table.insert(stone,v)
end
end
return stone,filler,top,dust
end
local function foundation(ground_p1,ground_p2,pos,sidelen)
local node_stone = "mcl_core:stone"
local node_filler = "mcl_core:dirt"
local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name
local node_dust = nil
if minetest.get_mapgen_setting("mg_name") ~= "v6" then
local b = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)]
--minetest.log(dump(b.node_top))
if b then
if b.node_top then node_top = b.node_top end
if b.node_filler then node_filler = b.node_filler end
if b.node_stone then node_stone = b.node_stone end
if b.node_dust then node_dust = b.node_dust end
end
end
local stone,filler,top,dust = get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone)
minetest.bulk_set_node(top,{name=node_top},node_stone)
if node_dust then
minetest.bulk_set_node(dust,{name=node_dust})
end
minetest.bulk_set_node(filler,{name=node_filler})
minetest.bulk_set_node(stone,{name=node_stone})
end
function mcl_structures.place_structure(pos, def, pr, blockseed) function mcl_structures.place_structure(pos, def, pr, blockseed)
if not def then return end if not def then return end
local logging = not def.terrain_feature local logging = not def.terrain_feature
@ -55,28 +144,7 @@ function mcl_structures.place_structure(pos, def, pr, blockseed)
local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"}) local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"})
if #solid < ( def.sidelen * def.sidelen ) then if #solid < ( def.sidelen * def.sidelen ) then
if def.make_foundation then if def.make_foundation then
local node_stone = "mcl_core:stone" foundation(vector.offset(pos,-def.sidelen/2 - 3,-1,-def.sidelen/2 - 3),vector.offset(pos,def.sidelen/2 + 3,-1,def.sidelen/2 + 3),pos,def.sidelen)
local node_filler = "mcl_core:dirt"
local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name
local node_dust = nil
if minetest.get_mapgen_setting("mg_name") ~= "v6" then
local b = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)]
--minetest.log(dump(b.node_top))
if b then
if b.node_top then node_top = b.node_top end
if b.node_filler then node_filler = b.node_filler end
if b.node_stone then node_stone = b.node_stone end
if b.node_dust then node_dust = b.node_dust end
end
end
local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves"}
minetest.bulk_set_node(minetest.find_nodes_in_area(ground_p1,ground_p2,replace),{name=node_top})
if node_dust then
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,1,0),vector.offset(ground_p2,0,1,0),{"air"}),{name=node_dust})
end
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-4,0),replace),{name=node_filler})
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-5,0),vector.offset(ground_p2,0,-30,0),replace),{name=node_stone})
else else
if logging then if logging then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.") minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.")
@ -122,6 +190,7 @@ function mcl_structures.place_structure(pos, def, pr, blockseed)
end end
function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly
if mcl_structures.is_disabled(name) then return end
local structblock = "mcl_structures:structblock_"..name local structblock = "mcl_structures:structblock_"..name
local flags = "place_center_x, place_center_z, force_placement" local flags = "place_center_x, place_center_z, force_placement"
local y_offset = 0 local y_offset = 0

View File

@ -16,11 +16,11 @@ local def = {
flags = "place_center_x, place_center_z, all_floors", flags = "place_center_x, place_center_z, all_floors",
solid_ground = true, solid_ground = true,
make_foundation = true, make_foundation = true,
chunk_probability = 400, chunk_probability = 800,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
y_min = 1, y_min = 1,
sidelen = 10, sidelen = 10,
y_offset = -4, y_offset = -5,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_ruined_portal_1.mts", modpath.."/schematics/mcl_structures_ruined_portal_1.mts",
modpath.."/schematics/mcl_structures_ruined_portal_2.mts", modpath.."/schematics/mcl_structures_ruined_portal_2.mts",

View File

@ -29,7 +29,7 @@ local function airtower(pos,tbl,h)
end end
end end
local function makelake(pos,size,liquid,placein,border,pr) local function makelake(pos,size,liquid,placein,border,pr,noair)
local node_under = minetest.get_node(vector.offset(pos,0,-1,0)) local node_under = minetest.get_node(vector.offset(pos,0,-1,0))
local p1 = vector.offset(pos,-size,-1,-size) local p1 = vector.offset(pos,-size,-1,-size)
local p2 = vector.offset(pos,size,-1,size) local p2 = vector.offset(pos,size,-1,size)
@ -70,7 +70,7 @@ local function makelake(pos,size,liquid,placein,border,pr)
end end
if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end
end end
if an.name ~= liquid then if not noair and an.name ~= liquid then
table.insert(br,pp) table.insert(br,pp)
if un.name ~= liquid then if un.name ~= liquid then
airtower(pp,air,55) airtower(pp,air,55)
@ -205,7 +205,28 @@ mcl_structures.register_structure("water_lake",{
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
y_min = minetest.get_mapgen_setting("water_level"), y_min = minetest.get_mapgen_setting("water_level"),
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block"},nil,pr) return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block"},"mcl_core:dirt_with_grass",pr)
end
})
mcl_structures.register_structure("water_lake_mangrove_swamp",{
place_on = {"mcl_mud:mud"},
biomes = { "MangroveSwamp" },
terrain_feature = true,
noise_params = {
offset = 0,
scale = 0.0032,
spread = {x = 250, y = 250, z = 250},
seed = 6343241353,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
flags = "place_center_x, place_center_z, force_placement",
y_max = mcl_vars.mg_overworld_max,
y_min = minetest.get_mapgen_setting("water_level"),
place_func = function(pos,def,pr)
return makelake(pos,3,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block","mcl_mud:mud"},"mcl_mud:mud",pr,true)
end end
}) })

View File

@ -1,8 +1,8 @@
mcl_playerplus = { mcl_playerplus = {
elytra = {}, elytra = {},
is_pressing_jump = {},
} }
local player_velocity_old = {x=0, y=0, z=0}
local get_connected_players = minetest.get_connected_players local get_connected_players = minetest.get_connected_players
local dir_to_yaw = minetest.dir_to_yaw local dir_to_yaw = minetest.dir_to_yaw
local get_item_group = minetest.get_item_group local get_item_group = minetest.get_item_group
@ -214,6 +214,26 @@ local function set_bone_position_conditional(player,b,p,r) --bone,position,rotat
player:set_bone_position(b,p,r) player:set_bone_position(b,p,r)
end end
local function get_overall_velocity(vector)
local v = math.sqrt(vector.x^2 + vector.y^2 + vector.z^2)
return v
end
local function anglediff(a1, a2)
local a = a1 - a2
return math.abs((a + math.pi) % (math.pi*2) - math.pi)
end
local function clamp(num, min, max)
return math.min(max, math.max(num, min))
end
local elytra_vars = {
slowdown_mult = 0.0, -- amount of vel to take per sec
fall_speed = 0.2, -- amount of vel to fall down per sec
speedup_mult = 2, -- amount of speed to add based on look dir
max_speed = 6, -- max amount to multiply against look direction when flying
pitch_penalty = 1.3, -- if pitching up, slow down at this rate as a multiplier
rocket_speed = 5.5,
}
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
@ -259,34 +279,53 @@ minetest.register_globalstep(function(dtime)
player_vel_yaws[name] = player_vel_yaw player_vel_yaws[name] = player_vel_yaw
local fly_pos = player:get_pos() local fly_pos = player:get_pos()
local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.5, z = fly_pos.z}).name local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.1, z = fly_pos.z}).name
local elytra = mcl_playerplus.elytra[player] local elytra = mcl_playerplus.elytra[player]
if not elytra.active then
elytra.speed = 0
end
local is_just_jumped = control.jump and not mcl_playerplus.is_pressing_jump[name] and not elytra.active
mcl_playerplus.is_pressing_jump[name] = control.jump
if is_just_jumped and not elytra.active then
local direction = player:get_look_dir()
elytra.speed = 1 - (direction.y/2 + 0.5)
end
elytra.active = player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" elytra.active = player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra"
and not player:get_attach() and not player:get_attach()
and (elytra.active or control.jump and player_velocity.y < -6) and (elytra.active or (is_just_jumped and player_velocity.y < -0))
and (fly_node == "air" or fly_node == "ignore") and ((not minetest.registered_nodes[fly_node].walkable) or fly_node == "ignore")
if elytra.active then if elytra.active then
if is_just_jumped then -- move the player up when they start flying to give some clearance
player:set_pos(vector.offset(player:get_pos(), 0, 0.8, 0))
end
mcl_player.player_set_animation(player, "fly") mcl_player.player_set_animation(player, "fly")
if player_velocity.y < -1.5 then local direction = player:get_look_dir()
player:add_velocity({x=0, y=0.17, z=0}) local player_vel = player:get_velocity()
end local turn_amount = anglediff(minetest.dir_to_yaw(direction), minetest.dir_to_yaw(player_vel))
if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then local direction_mult = clamp(-(direction.y+0.1), -1, 1)
local dir = minetest.yaw_to_dir(player:get_look_horizontal()) if direction_mult < 0 then direction_mult = direction_mult * elytra_vars.pitch_penalty end
if degrees(player:get_look_vertical()) * -.01 < .1 then
look_pitch = degrees(player:get_look_vertical()) * -.01
else
look_pitch = .1
end
player:add_velocity({x=dir.x, y=look_pitch, z=dir.z})
end
playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", 0.1)
local speed_mult = elytra.speed
local block_below = minetest.get_node(vector.offset(fly_pos, 0, -0.9, 0)).name
if (not minetest.registered_nodes[block_below].walkable) and (player_vel.y ~= 0) then
speed_mult = speed_mult + direction_mult * elytra_vars.speedup_mult * dtime
end
speed_mult = speed_mult - elytra_vars.slowdown_mult * clamp(dtime, 0.09, 0.2) -- slow down but don't overdo it
speed_mult = clamp(speed_mult, -elytra_vars.max_speed, elytra_vars.max_speed)
if turn_amount > 0.3 and math.abs(direction.y) < 0.98 then -- don't do this if looking straight up / down
speed_mult = speed_mult - (speed_mult * (turn_amount / (math.pi*8)))
end
playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", elytra_vars.fall_speed)
if elytra.rocketing > 0 then if elytra.rocketing > 0 then
elytra.rocketing = elytra.rocketing - dtime elytra.rocketing = elytra.rocketing - dtime
if vector.length(player_velocity) < 40 then if vector.length(player_velocity) < 40 then
player:add_velocity(vector.multiply(player:get_look_dir(), 4)) -- player:add_velocity(vector.multiply(player:get_look_dir(), 4))
speed_mult = elytra_vars.rocket_speed
add_particle({ add_particle({
pos = fly_pos, pos = fly_pos,
velocity = {x = 0, y = 0, z = 0}, velocity = {x = 0, y = 0, z = 0},
@ -300,7 +339,21 @@ minetest.register_globalstep(function(dtime)
}) })
end end
end end
else
elytra.speed = speed_mult -- set the speed so you can keep track of it and add to it
local new_vel = vector.multiply(direction, speed_mult * dtime * 30) -- use the look dir and speed as a mult
-- new_vel.y = new_vel.y - elytra_vars.fall_speed * dtime -- make the player fall a set amount
-- slow the player down so less spongy movement by applying some of the inverse velocity
-- NOTE: do not set this higher than about 0.2 or the game will get the wrong vel and it will be broken
-- this is far from ideal, but there's no good way to set_velocity or slow down the player
player_vel = vector.multiply(player_vel, -0.1)
-- if speed_mult < 1 then player_vel.y = player_vel.y * 0.1 end
new_vel = vector.add(new_vel, player_vel)
player:add_velocity(new_vel)
else -- reset things when you stop flying with elytra
elytra.rocketing = 0 elytra.rocketing = 0
playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra")
end end
@ -317,9 +370,6 @@ minetest.register_globalstep(function(dtime)
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90))
end end
player_velocity_old = player:get_velocity() or player:get_player_velocity()
-- controls right and left arms pitch when shooting a bow or blocking -- controls right and left arms pitch when shooting a bow or blocking
if mcl_shields.is_blocking(player) == 2 then if mcl_shields.is_blocking(player) == 2 then
set_bone_position_conditional(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0)) set_bone_position_conditional(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0))
@ -356,7 +406,7 @@ minetest.register_globalstep(function(dtime)
-- sets eye height, and nametag color accordingly -- sets eye height, and nametag color accordingly
set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
-- control body bone when flying -- control body bone when flying
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new((75-degrees(dir_to_pitch(player_velocity))) , -player_vel_yaw + yaw, 0))
elseif parent then elseif parent then
local parent_yaw = degrees(parent:get_yaw()) local parent_yaw = degrees(parent:get_yaw())
set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
@ -372,13 +422,13 @@ minetest.register_globalstep(function(dtime)
elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then
-- set head pitch and yaw when swimming -- set head pitch and yaw when swimming
is_swimming = true is_swimming = true
set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity))+20,player_vel_yaw - yaw,0))
-- sets eye height, and nametag color accordingly -- sets eye height, and nametag color accordingly
set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
-- control body bone when swimming -- control body bone when swimming
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new((75-degrees(dir_to_pitch(player_velocity))) , -player_vel_yaw + yaw, 0))
elseif get_item_group(mcl_playerinfo[name].node_head, "opaque") == 0 elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0
and get_item_group(mcl_playerinfo[name].node_head_top, "opaque") == 0 then and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then
-- sets eye height, and nametag color accordingly -- sets eye height, and nametag color accordingly
is_swimming = false is_swimming = false
set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) set_properties_conditional(player,{collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
@ -629,7 +679,7 @@ minetest.register_on_joinplayer(function(player)
swimDistance = 0, swimDistance = 0,
jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly
} }
mcl_playerplus.elytra[player] = {active = false, rocketing = 0} mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0}
end) end)
-- clear when player leaves -- clear when player leaves
@ -643,6 +693,9 @@ end)
-- Don't change HP if the player falls in the water or through End Portal: -- Don't change HP if the player falls in the water or through End Portal:
mcl_damage.register_modifier(function(obj, damage, reason) mcl_damage.register_modifier(function(obj, damage, reason)
if reason.type == "fall" then if reason.type == "fall" then
if minetest.is_creative_enabled(obj:get_player_name()) then
return 0
end
local pos = obj:get_pos() local pos = obj:get_pos()
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0} local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0}

View File

@ -39,6 +39,9 @@ mcl_doTileDrops (Blocks have drops) bool true
# If enabled, TNT explosions destroy blocks. # If enabled, TNT explosions destroy blocks.
mcl_tnt_griefing (TNT destroys blocks) bool true mcl_tnt_griefing (TNT destroys blocks) bool true
# Comma separated list of disabled structure names
mcl_disabled_structures (Disabled structures) string
[Players] [Players]
# If enabled, players respawn at the bed they last lay on instead of normal # If enabled, players respawn at the bed they last lay on instead of normal
# spawn. # spawn.
@ -112,6 +115,9 @@ animated_chests (Animated chests) bool true
# The maximum number of boss bars to simultaniously display on the screen # The maximum number of boss bars to simultaniously display on the screen
max_bossbars (Maximum Boss bars) int 5 max_bossbars (Maximum Boss bars) int 5
# Default intensity of shadows (default: 0.33)
mcl_default_shadow_intensity (Default shadow intensity) float 0.33 0.0 1.0
[Experimental] [Experimental]
# Whether ice is translucent. If disabled, ice is fully opaque. # Whether ice is translucent. If disabled, ice is fully opaque.
# #