Merge pull request 'Merge with master.' (#1) from MineClone2/MineClone2:master into master
Reviewed-on: https://git.minetest.land/ChrisPHP/MineClone2/pulls/1
|
@ -31,6 +31,7 @@
|
|||
* chmodsayshello
|
||||
* PrarieWind
|
||||
* RandomLegoBrick
|
||||
* SumianVoice
|
||||
|
||||
## Contributors
|
||||
* Laurent Rocher
|
||||
|
@ -79,6 +80,8 @@
|
|||
* MrRar
|
||||
* Lazerbeak12345
|
||||
* mrminer
|
||||
* Thunder1035
|
||||
* opfromthestart
|
||||
|
||||
## MineClone5
|
||||
* kay27
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}}
|
||||
},
|
||||
|
|
|
@ -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."),
|
||||
}
|
||||
|
|
42
mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj
Normal 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
|
42
mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj
Normal 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
|
42
mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj
Normal 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
|
Before Width: | Height: | Size: 676 B |
Before Width: | Height: | Size: 432 B |
Before Width: | Height: | Size: 970 B After Width: | Height: | Size: 382 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 432 B |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
|
|