diff --git a/CREDITS.md b/CREDITS.md index c2c59b504..db81b59fb 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -31,6 +31,7 @@ * chmodsayshello * PrarieWind * RandomLegoBrick +* SumianVoice ## Contributors * Laurent Rocher @@ -79,6 +80,8 @@ * MrRar * Lazerbeak12345 * mrminer +* Thunder1035 +* opfromthestart ## MineClone5 * kay27 diff --git a/README.md b/README.md index 01719a7a7..65eadbcc5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. Developed by many people. Not developed or endorsed by Mojang AB. -Version: 0.78 (in development) +Version: 0.79 (in development) ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 9775b8597..0b2d67730 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -24,6 +24,10 @@ local function is_ice(pos) return is_group(pos, "ice") end +local function is_fire(pos) + return is_group(pos, "set_on_fire") +end + local function get_sign(i) if i == 0 then return 0 @@ -218,6 +222,10 @@ function boat.on_step(self, dtime, moveresult) on_water = false if not in_water and is_ice(waterp) then 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 v_slowdown = 0.04 v_factor = 0.5 diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 5a82ca1fd..ccf1d2dca 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -847,8 +847,7 @@ minetest.register_entity(":__builtin:item", { elseif self._flowing == true and not is_in_water and not is_floating then -- Disable flowing physics if not on/in flowing liquid self._flowing = false - local pos = self.object:get_pos() - disable_physics(self.object, self, false, false) + disable_physics(self.object, self, true) return end diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 80a5b9318..d4b6c12e6 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -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 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 - 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() self.detach_timer = 0 return @@ -118,7 +119,7 @@ end mcl_mobs:register_mob("mobs_mc:parrot", { description = S("Parrot"), - type = "npc", + type = "passive", spawn_class = "passive", pathfinding = 1, hp_min = 6, diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg index 9c56b0f65..beae2bf1f 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg index bafc77b7e..39939308c 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg index 9e5c79b6d..148fbd48b 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg index 5c9ee492b..a1c5c24dd 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg index acb236445..5b436af59 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg index 1ef7a5227..50c4fa99a 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg index c2743fbcc..8054e1349 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg differ diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index a62db7158..f1caee61d 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -816,7 +816,7 @@ local function show_trade_formspec(playername, trader, tradenum) .."listring[current_player;main]" .."listring["..tradeinv..";input]" .."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) end @@ -878,13 +878,13 @@ local function update_offer(inv, player, sound) (trade.locked == false)) then inv:set_stack("output", 1, inv:get_stack("offered", 1)) 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 return true else inv:set_stack("output", 1, ItemStack("")) 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 return false end @@ -1084,7 +1084,8 @@ local trade_inventory = { if not wanted2:is_empty() then inv:remove_item("input", inv:get_stack("wanted", 2)) 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 update_offer(inv, player, true) end, @@ -1194,10 +1195,11 @@ local trade_inventory = { elseif listname == "input" then update_offer(inv, player, false) end + local trader = player_trading_with[name] 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 - 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, } diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index 2cf95022e..7dcc48637 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -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 get_connected_players = minetest.get_connected_players +local mgname = minetest.get_mapgen_setting("mg_name") mcl_weather.rain = { -- max rain particles created at time @@ -91,7 +92,7 @@ end function mcl_weather.rain.add_player(player) if mcl_weather.players[player:get_player_name()] == nil then 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 update_sound[player:get_player_name()]=true end diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index b70702b4c..a4108598f 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -246,7 +246,7 @@ mcl_weather.skycolor = { get_current_bg_color = function() local players = mcl_weather.skycolor.utils.get_players(nil) if players[1] then - return players[1]:get_sky() + return players[1]:get_sky(true).sky_color end return nil end @@ -276,6 +276,11 @@ minetest.register_globalstep(function(dtime) end) 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 mcl_weather.skycolor.force_update = true end diff --git a/mods/HUD/mcl_info/init.lua b/mods/HUD/mcl_info/init.lua index 5331a9bd6..71f8d8ad0 100644 --- a/mods/HUD/mcl_info/init.lua +++ b/mods/HUD/mcl_info/init.lua @@ -106,7 +106,7 @@ local function info() end after(refresh_interval, info) end -info() +minetest.after(0,info) minetest.register_on_leaveplayer(function(p) local name = p:get_player_name() diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 94f0fcd8d..dce69f26a 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -261,7 +261,7 @@ local dispenserdef = { local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(drop_vel * speed) + item_entity:set_velocity(vector.multiply(drop_vel,speed)) end else stack:take_item() @@ -278,7 +278,7 @@ local dispenserdef = { local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(drop_vel * speed) + item_entity:set_velocity(vector.multiply(drop_vel,speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 6dac4495f..b9c46d6b8 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -143,7 +143,7 @@ local dropperdef = { local item_entity = minetest.add_item(droppos, dropitem) local drop_vel = vector.subtract(droppos, pos) local speed = 3 - item_entity:set_velocity(drop_vel * speed) + item_entity:set_velocity(vector.multiply(drop_vel,speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index 012c32307..2606f8263 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -33,7 +33,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) local itemname = itemstack:get_name() 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") toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") diff --git a/mods/ITEMS/mcl_beacons/init.lua b/mods/ITEMS/mcl_beacons/init.lua index c484c949d..4614d5ce1 100644 --- a/mods/ITEMS/mcl_beacons/init.lua +++ b/mods/ITEMS/mcl_beacons/init.lua @@ -344,9 +344,6 @@ minetest.register_node("mcl_beacons:beacon", { mesecon.register_mvps_stopper("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 table.insert(beacon_blocklist, itemstring) end diff --git a/mods/ITEMS/mcl_beacons/mod.conf b/mods/ITEMS/mcl_beacons/mod.conf index 139a264b3..a8b7a467a 100644 --- a/mods/ITEMS/mcl_beacons/mod.conf +++ b/mods/ITEMS/mcl_beacons/mod.conf @@ -1,2 +1,3 @@ +name = mcl_beacons author=chmodsayshello depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 0e0f71a11..68ae4a829 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -49,6 +49,7 @@ minetest.register_node("mcl_core:water_flowing", { liquid_alternative_source = "mcl_core:water_source", liquid_viscosity = WATER_VISC, liquid_range = 7, + waving = 3, 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}, _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."), _doc_items_hidden = false, drawtype = "liquid", + waving = 3, tiles = { {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} }, diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index c14079393..69c26b97d 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local minetest = minetest local mod_doc = minetest.get_modpath("doc") local mod_screwdriver = minetest.get_modpath("screwdriver") @@ -8,159 +9,289 @@ if minetest.get_modpath("mcl_armor") then equip_armor = mcl_armor.equip_on_use end --- Heads system +mcl_heads = {} -local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) - local on_rotate_floor, on_rotate_wall - if mod_screwdriver then - on_rotate_floor = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = node.name .. "_wall" - node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - 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 +-- rotations of head nodes within a quadrant (0° ≤ θ ≤ 90°) +mcl_heads.FLOOR_DEGREES = { [0]='', '22_5', '45', '67_5', } + +-- 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 + node.name = node.name .. "_wall" + node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Allow pointed node's on_rightclick callback to override place. + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack end end - minetest.register_node("mcl_heads:"..name, { - 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}, + local above = pointed_thing.above + local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} + local wdir = minetest.dir_to_wallmounted(dir) + + local itemstring = itemstack:get_name() + local placestack = ItemStack(itemstack) + + -- place wall head node (elsewhere) + if wdir ~= 0 and wdir ~= 1 then + placestack:set_name(itemstring .."_wall") + itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + + -- place floor head node (floor and ceiling) + else + 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 + + -- restore item from angled and wall head nodes + itemstack:set_name(itemstring) + return itemstack +end + +-- wall head node nodedef template ------------------------------------------------------------------------------------- + +--- node definition template for wall mod heads +mcl_heads.deftemplate_wall = { + drawtype = "nodebox", + node_box = { + type = "wallmounted", + 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_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, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + 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_wall.on_rotate(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 + +-- API functions ------------------------------------------------------------------------------------------------------- + +--- @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. - "[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 + -- 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 }, - 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 - -- no interaction possible with entities, for now. - return itemstack - end - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end + _mcl_armor_mob_range_mob = head_def.range_mob, + _mcl_armor_mob_range_factor = head_def.range_factor, + _mcl_armor_texture = head_def.texture + })) - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local diff = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} - local wdir = minetest.dir_to_wallmounted(diff) - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - --local idef = fakestack:get_definition() - local retval - if wdir == 0 or wdir == 1 then - return minetest.item_place(itemstack, placer, pointed_thing) - else - retval = fakestack:set_name("mcl_heads:"..name.."_wall") - end - if not retval then - return itemstack - end - itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - return itemstack - end, - on_secondary_use = equip_armor, - - on_rotate = on_rotate_floor, - - _mcl_armor_mob_range_mob = rangemob, - _mcl_armor_mob_range_factor = rangefactor, - _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", - is_ground_content = false, - node_box = { - type = "wallmounted", - 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_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}, - -- The head textures are based off the textures of an actual mob. - tiles = { - { name = "[combine:16x16:-4,-4="..texture, align_style = "world" }, -- front - { name = "[combine:16x16:-20,-4="..texture, align_style = "world" }, -- back - { name = "[combine:16x16:-8,-4="..texture, align_style = "world" }, -- left - { 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, - paramtype = "light", - stack_max = 64, - paramtype2 = "wallmounted", - sunlight_propagates = true, - walkable = true, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - drop = "mcl_heads:"..name, - on_rotate = on_rotate_wall, - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - if mod_doc then - doc.add_entry_alias("nodes", "mcl_heads:" .. name, "nodes", "mcl_heads:" .. name .. "_wall") + -- 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 --- Add heads -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) +-- 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” -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.")) -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) -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.")) +mcl_heads.register_head{ + name = "steve", + 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."), +} diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj new file mode 100644 index 000000000..8e48015fc --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj @@ -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 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj new file mode 100644 index 000000000..6300d4484 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj @@ -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 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj new file mode 100644 index 000000000..0fe5567e3 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj @@ -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 diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png deleted file mode 100644 index 99b432ac6..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png deleted file mode 100644 index 0af86cd6a..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png index 361795a52..471a8b3c8 100644 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png and b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png deleted file mode 100644 index 43c1beb5a..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png deleted file mode 100644 index 671f40547..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png deleted file mode 100644 index ef85701e8..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png and /dev/null differ diff --git a/mods/ITEMS/mclx_core/init.lua b/mods/ITEMS/mclx_core/init.lua index 4bb40184a..9c46442c5 100644 --- a/mods/ITEMS/mclx_core/init.lua +++ b/mods/ITEMS/mclx_core/init.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) local source = table.copy(minetest.registered_nodes["mcl_core:water_source"]) source.description = S("River Water Source") source.liquid_range = 2 +source.waving = 3 source.liquid_alternative_flowing = "mclx_core:river_water_flowing" source.liquid_alternative_source = "mclx_core:river_water_source" source.liquid_renewable = false @@ -28,6 +29,7 @@ source.special_tiles = { local flowing = table.copy(minetest.registered_nodes["mcl_core:water_flowing"]) flowing.description = S("Flowing River Water") flowing.liquid_range = 2 +flowing.waving = 3 flowing.liquid_alternative_flowing = "mclx_core:river_water_flowing" flowing.liquid_alternative_source = "mclx_core:river_water_source" flowing.liquid_renewable = false diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua index af08caf07..e57d4f6be 100644 --- a/mods/MAPGEN/mcl_structures/api.lua +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -1,5 +1,12 @@ 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) for it,lt in pairs(loot) do @@ -38,6 +45,88 @@ function mcl_structures.find_highest_y(pp) return y 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) if not def then return end 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"}) if #solid < ( def.sidelen * def.sidelen ) then if def.make_foundation then - 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 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}) + 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) else if logging then 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 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 flags = "place_center_x, place_center_z, force_placement" local y_offset = 0 diff --git a/mods/MAPGEN/mcl_structures/ruined_portal.lua b/mods/MAPGEN/mcl_structures/ruined_portal.lua index 002195f76..00d2d682c 100644 --- a/mods/MAPGEN/mcl_structures/ruined_portal.lua +++ b/mods/MAPGEN/mcl_structures/ruined_portal.lua @@ -16,11 +16,11 @@ local def = { flags = "place_center_x, place_center_z, all_floors", solid_ground = true, make_foundation = true, - chunk_probability = 400, + chunk_probability = 800, y_max = mcl_vars.mg_overworld_max, y_min = 1, sidelen = 10, - y_offset = -4, + y_offset = -5, filenames = { modpath.."/schematics/mcl_structures_ruined_portal_1.mts", modpath.."/schematics/mcl_structures_ruined_portal_2.mts", diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts index ae37576dc..55a6f2ae3 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts index fd17f1365..9da16e2ed 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts index 0834d8923..463bf19df 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts differ diff --git a/mods/MAPGEN/mcl_terrain_features/init.lua b/mods/MAPGEN/mcl_terrain_features/init.lua index 18f242e36..eab33e78e 100644 --- a/mods/MAPGEN/mcl_terrain_features/init.lua +++ b/mods/MAPGEN/mcl_terrain_features/init.lua @@ -29,7 +29,7 @@ local function airtower(pos,tbl,h) 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 p1 = 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 if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end end - if an.name ~= liquid then + if not noair and an.name ~= liquid then table.insert(br,pp) if un.name ~= liquid then airtower(pp,air,55) @@ -205,7 +205,28 @@ mcl_structures.register_structure("water_lake",{ y_max = mcl_vars.mg_overworld_max, y_min = minetest.get_mapgen_setting("water_level"), 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 }) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index c3876269c..8756846ce 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,8 +1,8 @@ mcl_playerplus = { elytra = {}, + is_pressing_jump = {}, } -local player_velocity_old = {x=0, y=0, z=0} local get_connected_players = minetest.get_connected_players local dir_to_yaw = minetest.dir_to_yaw 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) 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) @@ -259,34 +279,53 @@ minetest.register_globalstep(function(dtime) player_vel_yaws[name] = player_vel_yaw 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] + 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" and not player:get_attach() - and (elytra.active or control.jump and player_velocity.y < -6) - and (fly_node == "air" or fly_node == "ignore") + and (elytra.active or (is_just_jumped and player_velocity.y < -0)) + and ((not minetest.registered_nodes[fly_node].walkable) or fly_node == "ignore") 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") - if player_velocity.y < -1.5 then - player:add_velocity({x=0, y=0.17, z=0}) - end - if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then - local dir = minetest.yaw_to_dir(player:get_look_horizontal()) - 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 direction = player:get_look_dir() + local player_vel = player:get_velocity() + local turn_amount = anglediff(minetest.dir_to_yaw(direction), minetest.dir_to_yaw(player_vel)) + local direction_mult = clamp(-(direction.y+0.1), -1, 1) + if direction_mult < 0 then direction_mult = direction_mult * elytra_vars.pitch_penalty end + 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 elytra.rocketing = elytra.rocketing - dtime 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({ pos = fly_pos, velocity = {x = 0, y = 0, z = 0}, @@ -300,7 +339,21 @@ minetest.register_globalstep(function(dtime) }) 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 playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") 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)) end - player_velocity_old = player:get_velocity() or player:get_player_velocity() - - -- controls right and left arms pitch when shooting a bow or blocking 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)) @@ -356,7 +406,7 @@ minetest.register_globalstep(function(dtime) -- 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 }}) -- 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 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 }}) @@ -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 -- set head pitch and yaw when swimming 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 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 - 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)) - elseif get_item_group(mcl_playerinfo[name].node_head, "opaque") == 0 - and get_item_group(mcl_playerinfo[name].node_head_top, "opaque") == 0 then + 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, "solid") == 0 + and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then -- sets eye height, and nametag color accordingly 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 }}) @@ -629,7 +679,7 @@ minetest.register_on_joinplayer(function(player) swimDistance = 0, 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) -- clear when player leaves @@ -643,6 +693,9 @@ end) -- Don't change HP if the player falls in the water or through End Portal: mcl_damage.register_modifier(function(obj, damage, reason) if reason.type == "fall" then + if minetest.is_creative_enabled(obj:get_player_name()) then + return 0 + end local pos = obj:get_pos() local node = minetest.get_node(pos) local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0} diff --git a/settingtypes.txt b/settingtypes.txt index 35db8bde7..a883905c6 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -39,6 +39,9 @@ mcl_doTileDrops (Blocks have drops) bool true # If enabled, TNT explosions destroy blocks. mcl_tnt_griefing (TNT destroys blocks) bool true +# Comma separated list of disabled structure names +mcl_disabled_structures (Disabled structures) string + [Players] # If enabled, players respawn at the bed they last lay on instead of normal # spawn. @@ -112,6 +115,9 @@ animated_chests (Animated chests) bool true # The maximum number of boss bars to simultaniously display on the screen 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] # Whether ice is translucent. If disabled, ice is fully opaque. #