forked from VoxeLibre/VoxeLibre
Merge branch 'master' into master
This commit is contained in:
commit
5329e70df9
|
@ -853,9 +853,10 @@ minetest.register_entity(":__builtin:item", {
|
|||
|
||||
-- If node is not registered or node is walkably solid and resting on nodebox
|
||||
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||
local def = minetest.registered_nodes[nn]
|
||||
local v = self.object:get_velocity()
|
||||
local is_on_floor = (minetest.registered_nodes[nn].walkable
|
||||
and not minetest.registered_nodes[nn].groups.slippery and v.y == 0)
|
||||
local is_on_floor = def and (def.walkable
|
||||
and not def.groups.slippery and v.y == 0)
|
||||
|
||||
if not minetest.registered_nodes[nn]
|
||||
or is_floating or is_on_floor then
|
||||
|
|
|
@ -213,11 +213,11 @@ end
|
|||
local collision = function(self)
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return {0,0} end
|
||||
local vel = self.object:get_velocity()
|
||||
local x = 0
|
||||
local z = 0
|
||||
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||
|
||||
local ent = object:get_luaentity()
|
||||
|
@ -254,12 +254,14 @@ local set_velocity = function(self, v)
|
|||
end
|
||||
|
||||
local yaw = (self.object:get_yaw() or 0) + self.rotate
|
||||
|
||||
self.object:set_velocity({
|
||||
x = (sin(yaw) * -v) + c_x,
|
||||
y = self.object:get_velocity().y,
|
||||
z = (cos(yaw) * v) + c_y,
|
||||
})
|
||||
local vv = self.object:get_velocity()
|
||||
if vv then
|
||||
self.object:set_velocity({
|
||||
x = (sin(yaw) * -v) + c_x,
|
||||
y = vv.y,
|
||||
z = (cos(yaw) * v) + c_y,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -3002,6 +3004,7 @@ end
|
|||
|
||||
local function check_entity_cramming(self)
|
||||
local p = self.object:get_pos()
|
||||
if not p then return end
|
||||
local oo = minetest.get_objects_inside_radius(p,1)
|
||||
local mobs = {}
|
||||
for _,o in pairs(oo) do
|
||||
|
@ -3467,7 +3470,10 @@ local mob_activate = function(self, staticdata, def, dtime)
|
|||
def.textures = {def.textures}
|
||||
end
|
||||
|
||||
self.base_texture = def.textures[random(1, #def.textures)]
|
||||
local c = 1
|
||||
if #def.textures > c then c = #def.textures end
|
||||
|
||||
self.base_texture = def.textures[math.random(c)]
|
||||
self.base_mesh = def.mesh
|
||||
self.base_size = self.visual_size
|
||||
self.base_colbox = self.collisionbox
|
||||
|
|
|
@ -23,7 +23,8 @@ local table_copy = table.copy
|
|||
local table_remove = table.remove
|
||||
|
||||
local pairs = pairs
|
||||
|
||||
local dbg_spawn_attempts = 0
|
||||
local dbg_spawn_succ = 0
|
||||
-- range for mob count
|
||||
local aoc_range = 136
|
||||
|
||||
|
@ -416,47 +417,87 @@ local function get_water_spawn(p)
|
|||
end
|
||||
end
|
||||
|
||||
local dbg_spawn_attempts = 0
|
||||
local dbg_spawn_succ = 0
|
||||
local function spawn_check(pos,spawn_def)
|
||||
if not spawn_def then return end
|
||||
dbg_spawn_attempts = dbg_spawn_attempts + 1
|
||||
local dimension = mcl_worlds.pos_to_dimension(pos)
|
||||
local mob_type = minetest.registered_entities[spawn_def.name].type
|
||||
local gotten_node = get_node(pos).name
|
||||
local gotten_biome = minetest.get_biome_data(pos)
|
||||
if not gotten_node or not gotten_biome then return end
|
||||
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
|
||||
|
||||
local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
|
||||
if not is_ground then
|
||||
pos.y = pos.y - 1
|
||||
gotten_node = get_node(pos).name
|
||||
is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
|
||||
local is_water = get_item_group(gotten_node, "water") ~= 0
|
||||
local is_lava = get_item_group(gotten_node, "lava") ~= 0
|
||||
local is_leaf = get_item_group(gotten_node, "leaves") ~= 0
|
||||
local is_bedrock = gotten_node == "mcl_core:bedrock"
|
||||
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
|
||||
local mob_count_wide = count_mobs(pos,aoc_range,mob_type)
|
||||
local mob_count = count_mobs(pos,32,mob_type)
|
||||
|
||||
if pos and spawn_def
|
||||
and mob_count_wide < (mob_cap[mob_type] or 15)
|
||||
and mob_count < 5
|
||||
and pos.y >= spawn_def.min_height
|
||||
and pos.y <= spawn_def.max_height
|
||||
and spawn_def.dimension == dimension
|
||||
and biome_check(spawn_def.biomes, gotten_biome)
|
||||
and (is_ground or spawn_def.type_of_spawning ~= "ground")
|
||||
and (spawn_def.type_of_spawning ~= "ground" or not is_leaf)
|
||||
and (spawn_def.check_position and spawn_def.check_position(pos) or true)
|
||||
and (not is_farm_animal(spawn_def.name) or is_grass)
|
||||
and (spawn_def.type_of_spawning ~= "water" or is_water)
|
||||
and not is_bedrock then
|
||||
--only need to poll for node light if everything else worked
|
||||
local gotten_light = get_node_light(pos)
|
||||
if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function spawn_group(p,mob,spawn_on,group_max,group_min)
|
||||
if not group_min then group_min = 1 end
|
||||
local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on)
|
||||
local o
|
||||
table.shuffle(nn)
|
||||
if not nn or #nn < 1 then
|
||||
nn = {}
|
||||
table.insert(nn,p)
|
||||
end
|
||||
for i = 1, math.random(group_min,group_max) do
|
||||
local sp = vector.offset(nn[math.random(#nn)],0,1,0)
|
||||
if mob.type_of_spawning == "water" then
|
||||
sp = get_water_spawn(sp)
|
||||
if spawn_check(nn[math.random(#nn)],mob) then
|
||||
if mob.type_of_spawning == "water" then
|
||||
sp = get_water_spawn(sp)
|
||||
end
|
||||
o = minetest.add_entity(sp,mob.name)
|
||||
if o then dbg_spawn_succ = dbg_spawn_succ + 1 end
|
||||
end
|
||||
o = minetest.add_entity(sp,mob.name)
|
||||
if o then dbg_spawn_succ = dbg_spawn_succ + 1 end
|
||||
end
|
||||
return o
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("mobstats",{
|
||||
privs = { debug = true },
|
||||
func = function(n,param)
|
||||
local pos = minetest.get_player_by_name(n):get_pos()
|
||||
minetest.chat_send_player(n,"mobs within 32 radius of player:"..count_mobs(pos,32))
|
||||
minetest.chat_send_player(n,"total mobs:"..count_mobs_total())
|
||||
minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts)
|
||||
minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ)
|
||||
end
|
||||
})
|
||||
|
||||
if mobs_spawn then
|
||||
|
||||
local perlin_noise
|
||||
|
||||
local function spawn_a_mob(pos, dimension, y_min, y_max)
|
||||
dbg_spawn_attempts = dbg_spawn_attempts + 1
|
||||
local dimension = dimension or mcl_worlds.pos_to_dimension(pos)
|
||||
--create a disconnected clone of the spawn dictionary
|
||||
--prevents memory leak
|
||||
local mob_library_worker_table = table_copy(spawn_dictionary)
|
||||
local goal_pos = get_next_mob_spawn_pos(pos)
|
||||
--grab mob that fits into the spawning location
|
||||
--randomly grab a mob, don't exclude any possibilities
|
||||
local spawning_position_list = find_nodes_in_area_under_air(
|
||||
{x = goal_pos.x, y = y_min, z = goal_pos.z},
|
||||
{x = goal_pos.x, y = y_max, z = goal_pos.z},
|
||||
|
@ -465,37 +506,6 @@ if mobs_spawn then
|
|||
if #spawning_position_list <= 0 then return end
|
||||
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
|
||||
|
||||
local gotten_node = get_node(spawning_position).name
|
||||
local gotten_biome = minetest.get_biome_data(spawning_position)
|
||||
if not gotten_node or not gotten_biome then return end
|
||||
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
|
||||
|
||||
--add this so mobs don't spawn inside nodes
|
||||
spawning_position.y = spawning_position.y + 1
|
||||
|
||||
--only need to poll for node light if everything else worked
|
||||
local gotten_light = get_node_light(spawning_position)
|
||||
|
||||
local is_water = get_item_group(gotten_node, "water") ~= 0
|
||||
local is_lava = get_item_group(gotten_node, "lava") ~= 0
|
||||
local is_leaf = get_item_group(gotten_node, "leaves") ~= 0
|
||||
local is_bedrock = gotten_node == "mcl_core:bedrock"
|
||||
local is_ground = not (is_water or is_lava)
|
||||
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
|
||||
local has_bed = minetest.find_node_near(pos,25,{"group:bed"})
|
||||
|
||||
if not is_ground then
|
||||
spawning_position.y = spawning_position.y - 1
|
||||
end
|
||||
|
||||
local mob_def
|
||||
|
||||
--create a disconnected clone of the spawn dictionary
|
||||
--prevents memory leak
|
||||
local mob_library_worker_table = table_copy(spawn_dictionary)
|
||||
|
||||
--grab mob that fits into the spawning location
|
||||
--randomly grab a mob, don't exclude any possibilities
|
||||
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
|
||||
local noise = perlin_noise:get_3d(spawning_position)
|
||||
local current_summary_chance = summary_chance
|
||||
|
@ -511,28 +521,10 @@ if mobs_spawn then
|
|||
step_chance = step_chance + mob_chance
|
||||
end
|
||||
local mob_def = mob_library_worker_table[mob_index]
|
||||
local mob_type = minetest.registered_entities[mob_def.name].type
|
||||
local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4
|
||||
local spawn_in_group_min = minetest.registered_entities[mob_def.name].spawn_in_group_min or 1
|
||||
local mob_count_wide = count_mobs(pos,aoc_range,mob_type)
|
||||
local mob_count = count_mobs(spawning_position,32,mob_type)
|
||||
if mob_def
|
||||
and mob_count_wide < (mob_cap[mob_type] or 15)
|
||||
and mob_count < 5
|
||||
and spawning_position.y >= mob_def.min_height
|
||||
and spawning_position.y <= mob_def.max_height
|
||||
and mob_def.dimension == dimension
|
||||
and biome_check(mob_def.biomes, gotten_biome)
|
||||
and gotten_light >= mob_def.min_light
|
||||
and gotten_light <= mob_def.max_light
|
||||
and (is_ground or mob_def.type_of_spawning ~= "ground")
|
||||
and (mob_def.type_of_spawning ~= "ground" or not is_leaf)
|
||||
and (mob_def.check_position and mob_def.check_position(spawning_position) or true)
|
||||
and (not is_farm_animal(mob_def.name) or is_grass)
|
||||
and (mob_type ~= "npc" or has_bed)
|
||||
and (mob_def.type_of_spawning ~= "water" or is_water)
|
||||
and not is_bedrock
|
||||
then
|
||||
local mob_type = minetest.registered_entities[mob_def.name].type
|
||||
if spawn_check(spawning_position,mob_def) then
|
||||
if mob_def.type_of_spawning == "water" then
|
||||
spawning_position = get_water_spawn(spawning_position)
|
||||
if not spawning_position then
|
||||
|
@ -544,9 +536,10 @@ if mobs_spawn then
|
|||
end
|
||||
--everything is correct, spawn mob
|
||||
local object
|
||||
if spawn_in_group then
|
||||
object = spawn_group(spawning_position,mob_def,{gotten_node},spawn_in_group,spawn_in_group_min)
|
||||
else object = minetest.add_entity(spawning_position, mob_def.name)
|
||||
if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then
|
||||
object = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name},spawn_in_group,spawn_in_group_min)
|
||||
else
|
||||
object = minetest.add_entity(spawning_position, mob_def.name)
|
||||
end
|
||||
|
||||
|
||||
|
@ -580,3 +573,14 @@ if mobs_spawn then
|
|||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("mobstats",{
|
||||
privs = { debug = true },
|
||||
func = function(n,param)
|
||||
local pos = minetest.get_player_by_name(n):get_pos()
|
||||
minetest.chat_send_player(n,"mobs within 32 radius of player:"..count_mobs(pos,32))
|
||||
minetest.chat_send_player(n,"total mobs:"..count_mobs_total())
|
||||
minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts)
|
||||
minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ)
|
||||
end
|
||||
})
|
||||
|
|
|
@ -12,6 +12,7 @@ local S = minetest.get_translator("mobs_mc")
|
|||
mcl_mobs:register_mob("mobs_mc:creeper", {
|
||||
type = "monster",
|
||||
spawn_class = "hostile",
|
||||
spawn_in_group = 1,
|
||||
hp_min = 20,
|
||||
hp_max = 20,
|
||||
xp_min = 5,
|
||||
|
|
|
@ -219,6 +219,7 @@ local select_enderman_animation = function(animation_type)
|
|||
end
|
||||
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
local spawners = {}
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:enderman", {
|
||||
description = S("Enderman"),
|
||||
|
@ -263,20 +264,42 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
|
|||
do_custom = function(self, dtime)
|
||||
-- PARTICLE BEHAVIOUR HERE.
|
||||
local enderpos = self.object:get_pos()
|
||||
local chanceOfParticle = math.random(0, 1)
|
||||
if chanceOfParticle == 1 then
|
||||
minetest.add_particle({
|
||||
pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2},
|
||||
velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)},
|
||||
acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)},
|
||||
expirationtime = math.random(),
|
||||
size = math.random(),
|
||||
collisiondetection = true,
|
||||
vertical = false,
|
||||
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
|
||||
})
|
||||
if self._particle_timer and self._particle_timer >= 1 then
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
if not spawners[player] then spawners[player] = {} end
|
||||
local dst = vector.distance(player:get_pos(),enderpos)
|
||||
if dst < 128 and not spawners[player][self.object] then
|
||||
self._particle_timer = 0
|
||||
spawners[player][self.object] = minetest.add_particlespawner({
|
||||
amount = 5,
|
||||
minpos = vector.new(-0.6,0,-0.6),
|
||||
maxpos = vector.new(0.6,3,0.6),
|
||||
minvel = vector.new(-0.25,-0.25,-0.25),
|
||||
maxvel = vector.new(0.25,0.25,0.25),
|
||||
minacc = vector.new(-0.5,-0.5,-0.5),
|
||||
maxacc = vector.new(0.5,0.5,0.5),
|
||||
minexptime = 0.2,
|
||||
maxexptime = 3,
|
||||
minsize = 0.2,
|
||||
maxsize = 1.2,
|
||||
collisiondetection = true,
|
||||
vertical = false,
|
||||
time = 0,
|
||||
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
|
||||
attached = self.object,
|
||||
playername = player:get_player_name(),
|
||||
})
|
||||
elseif dst > 128 and spawners[player][self.object] then
|
||||
minetest.delete_particlespawner(spawners[player][self.object])
|
||||
spawners[player][self.object] = nil
|
||||
end
|
||||
end
|
||||
elseif not self._particle_timer then
|
||||
self._particle_timer = 0
|
||||
end
|
||||
self._particle_timer = self._particle_timer + dtime
|
||||
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
|
||||
enderpos = self.object:get_pos()
|
||||
local dim = mcl_worlds.pos_to_dimension(enderpos)
|
||||
if dim == "overworld" then
|
||||
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
|
||||
|
@ -593,6 +616,13 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
|
|||
attack_type = "dogfight",
|
||||
})
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
for _,s in pairs(spawners[player]) do
|
||||
minetest.delete_particlespawner(s)
|
||||
end
|
||||
spawners[player] = nil
|
||||
end)
|
||||
|
||||
|
||||
-- End spawn
|
||||
mcl_mobs:spawn_specific(
|
||||
|
|
Binary file not shown.
|
@ -72,7 +72,7 @@ local tropical_fish = {
|
|||
collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2},
|
||||
visual = "mesh",
|
||||
mesh = "extra_mobs_tropical_fish_a.b3d",
|
||||
textures = {}, -- to be populated on_spawn
|
||||
textures = { "extra_mobs_tropical_fish_a.png" }, -- to be populated on_spawn
|
||||
sounds = {},
|
||||
animation = {
|
||||
stand_start = 0,
|
||||
|
|
|
@ -591,6 +591,51 @@ local function go_home(entity)
|
|||
end)
|
||||
end
|
||||
|
||||
local function has_golem(pos)
|
||||
local r = false
|
||||
for _,o in pairs(minetest.get_objects_inside_radius(pos,16)) do
|
||||
local l = o:get_luaentity()
|
||||
if l and l.name == "mobs_mc:iron_golem" then return true end
|
||||
end
|
||||
end
|
||||
|
||||
local function has_summon_participants(self)
|
||||
local r = 0
|
||||
for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do
|
||||
local l = o:get_luaentity()
|
||||
--TODO check for panicking or gossiping
|
||||
if l and l.name == "mobs_mc:villager" then r = r + 1 end
|
||||
end
|
||||
return r > 2
|
||||
end
|
||||
|
||||
local function summon_golem(self)
|
||||
vector.offset(self.object:get_pos(),-10,-10,-10)
|
||||
local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.object:get_pos(),-10,-10,-10),vector.offset(self.object:get_pos(),10,10,10),{"group:solid","group:water"})
|
||||
table.shuffle(nn)
|
||||
for _,n in pairs(nn) do
|
||||
local up = minetest.find_nodes_in_area(vector.offset(n,0,1,0),vector.offset(n,0,3,0),{"air"})
|
||||
if up and #up >= 3 then
|
||||
minetest.sound_play("mcl_portals_open_end_portal", {pos=n, gain=0.5, max_hear_distance = 16}, true)
|
||||
return minetest.add_entity(vector.offset(n,0,1,0),"mobs_mc:iron_golem")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function check_summon(self,dtime)
|
||||
-- TODO has selpt in last 20?
|
||||
if self._summon_timer and self._summon_timer > 30 then
|
||||
local pos = self.object:get_pos()
|
||||
self._summon_timer = 0
|
||||
if has_golem(pos) then return false end
|
||||
if not has_summon_participants(self) then return end
|
||||
summon_golem(self)
|
||||
elseif self._summon_timer == nil then
|
||||
self._summon_timer = 0
|
||||
end
|
||||
self._summon_timer = self._summon_timer + dtime
|
||||
end
|
||||
|
||||
----- JOBSITE LOGIC
|
||||
local function get_profession_by_jobsite(js)
|
||||
for k,v in pairs(professions) do
|
||||
|
@ -1337,6 +1382,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
|||
_player_scan_timer = 0,
|
||||
_trading_players = {}, -- list of playernames currently trading with villager (open formspec)
|
||||
do_custom = function(self, dtime)
|
||||
check_summon(self,dtime)
|
||||
-- Stand still if player is nearby.
|
||||
if not self._player_scan_timer then
|
||||
self._player_scan_timer = 0
|
||||
|
|
|
@ -55,7 +55,7 @@ local zombie = {
|
|||
xp_max = 5,
|
||||
breath_max = -1,
|
||||
armor = {undead = 90, fleshy = 90},
|
||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
|
||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.8, 0.3},
|
||||
visual = "mesh",
|
||||
mesh = "mobs_mc_zombie.b3d",
|
||||
textures = {
|
||||
|
@ -65,7 +65,6 @@ local zombie = {
|
|||
"mobs_mc_empty.png", -- wielded_item
|
||||
}
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_mc_zombie_growl",
|
||||
|
@ -85,16 +84,23 @@ local zombie = {
|
|||
group_attack = { "mobs_mc:zombie", "mobs_mc:baby_zombie", "mobs_mc:husk", "mobs_mc:baby_husk" },
|
||||
drops = drops_zombie,
|
||||
animation = {
|
||||
speed_normal = 25, speed_run = 50,
|
||||
stand_start = 40, stand_end = 80,
|
||||
walk_start = 0, walk_end = 40,
|
||||
run_start = 0, run_end = 40,
|
||||
stand_start = 40, stand_end = 49, stand_speed = 2,
|
||||
walk_start = 0, walk_end = 39, speed_normal = 25,
|
||||
run_start = 0, run_end = 39, speed_run = 50,
|
||||
punch_start = 50, punch_end = 59, punch_speed = 20,
|
||||
},
|
||||
ignited_by_sunlight = true,
|
||||
sunlight_damage = 2,
|
||||
view_range = 16,
|
||||
attack_type = "dogfight",
|
||||
harmed_by_heal = true,
|
||||
on_spawn = function(self)
|
||||
-- Remove saved visual_size on old existing entites.
|
||||
-- Old entities were 3 now it's 1.
|
||||
self.visual_size = nil
|
||||
self.object:set_properties({visual_size = self.visual_size})
|
||||
self.base_size = self.visual_size
|
||||
end,
|
||||
}
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:zombie", zombie)
|
||||
|
@ -104,13 +110,20 @@ mcl_mobs:register_mob("mobs_mc:zombie", zombie)
|
|||
|
||||
local baby_zombie = table.copy(zombie)
|
||||
baby_zombie.description = S("Baby Zombie")
|
||||
baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25}
|
||||
baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 1, 0.25}
|
||||
baby_zombie.xp_min = 12
|
||||
baby_zombie.xp_max = 12
|
||||
baby_zombie.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2}
|
||||
baby_zombie.visual_size = {x = 1 / 2, y = 1 / 2}
|
||||
baby_zombie.walk_velocity = 1.2
|
||||
baby_zombie.run_velocity = 2.4
|
||||
baby_zombie.child = 1
|
||||
baby_zombie.reach = 1
|
||||
baby_zombie.animation = {
|
||||
stand_start = 100, stand_end = 109, stand_speed = 2,
|
||||
walk_start = 60, walk_end = 99, speed_normal = 40,
|
||||
run_start = 60, run_end = 99, speed_run = 80,
|
||||
punch_start = 109, punch_end = 119
|
||||
}
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:baby_zombie", baby_zombie)
|
||||
|
||||
|
@ -134,15 +147,16 @@ mcl_mobs:register_mob("mobs_mc:husk", husk)
|
|||
|
||||
-- Baby husk.
|
||||
-- A smaller and more dangerous variant of the husk
|
||||
local baby_husk = table.copy(husk)
|
||||
local baby_husk = table.copy(baby_zombie)
|
||||
baby_husk.description = S("Baby Husk")
|
||||
baby_husk.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25}
|
||||
baby_husk.xp_min = 12
|
||||
baby_husk.xp_max = 12
|
||||
baby_husk.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2}
|
||||
baby_husk.walk_velocity = 1.2
|
||||
baby_husk.run_velocity = 2.4
|
||||
baby_husk.child = 1
|
||||
baby_husk.textures = {{
|
||||
"mobs_mc_empty.png", -- armor
|
||||
"mobs_mc_husk.png", -- texture
|
||||
"mobs_mc_empty.png", -- wielded_item
|
||||
}}
|
||||
baby_husk.ignited_by_sunlight = false
|
||||
baby_husk.sunlight_damage = 0
|
||||
baby_husk.drops = drops_common
|
||||
|
||||
mcl_mobs:register_mob("mobs_mc:baby_husk", baby_husk)
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,6 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local F = minetest.formspec_escape
|
||||
local C = minetest.colorize
|
||||
|
||||
local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book
|
||||
local max_title_length = 64
|
||||
|
@ -331,6 +333,75 @@ if minetest.get_modpath("mcl_sounds") then
|
|||
wood_sound = mcl_sounds.node_sound_wood_defaults()
|
||||
end
|
||||
|
||||
-- Bookshelf GUI
|
||||
local drop_content = mcl_util.drop_items_from_meta_container("main")
|
||||
|
||||
local function on_blast(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
drop_content(pos, node)
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
|
||||
-- Simple protection checking functions
|
||||
local function protection_check_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local name = player:get_player_name()
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return 0
|
||||
else
|
||||
return count
|
||||
end
|
||||
end
|
||||
|
||||
local function protection_check_put_take(pos, listname, index, stack, player)
|
||||
local name = player:get_player_name()
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return 0
|
||||
elseif minetest.get_item_group(stack:get_name(), "book") ~= 0 or stack:get_name() == "mcl_enchanting:book_enchanted" then
|
||||
return stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local function bookshelf_gui(pos, node, clicker)
|
||||
local name = minetest.get_meta(pos):get_string("name")
|
||||
|
||||
if name == "" then
|
||||
name = S("Bookshelf")
|
||||
end
|
||||
|
||||
local playername = clicker:get_player_name()
|
||||
|
||||
minetest.show_formspec(playername,
|
||||
"mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z,
|
||||
table.concat({
|
||||
"size[9,8.75]",
|
||||
"label[0,0;"..F(C("#313131", name)).."]",
|
||||
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]",
|
||||
mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3),
|
||||
"label[0,4.0;"..F(C("#313131", S("Inventory"))).."]",
|
||||
"list[current_player;main;0,4.5;9,3;9]",
|
||||
mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3),
|
||||
"list[current_player;main;0,7.74;9,1;]",
|
||||
mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1),
|
||||
"listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]",
|
||||
"listring[current_player;main]",
|
||||
})
|
||||
)
|
||||
end
|
||||
|
||||
local function close_forms(pos)
|
||||
local players = minetest.get_connected_players()
|
||||
local formname = "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z
|
||||
for p = 1, #players do
|
||||
if vector.distance(players[p]:get_pos(), pos) <= 30 then
|
||||
minetest.close_formspec(players[p]:get_player_name(), formname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Bookshelf
|
||||
minetest.register_node("mcl_books:bookshelf", {
|
||||
description = S("Bookshelf"),
|
||||
|
@ -340,13 +411,40 @@ minetest.register_node("mcl_books:bookshelf", {
|
|||
is_ground_content = false,
|
||||
groups = {
|
||||
handy=1, axey=1, deco_block=1, material_wood=1,
|
||||
flammable=3, fire_encouragement=30, fire_flammability=20
|
||||
flammable=3, fire_encouragement=30, fire_flammability=20, container=1
|
||||
},
|
||||
drop = "mcl_books:book 3",
|
||||
sounds = wood_sound,
|
||||
_mcl_blast_resistance = 1.5,
|
||||
_mcl_hardness = 1.5,
|
||||
_mcl_silk_touch_drop = true,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 9*3)
|
||||
end,
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name"))
|
||||
end,
|
||||
allow_metadata_inventory_move = protection_check_move,
|
||||
allow_metadata_inventory_take = protection_check_put_take,
|
||||
allow_metadata_inventory_put = protection_check_put_take,
|
||||
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" moves stuff in bookshelf at "..minetest.pos_to_string(pos))
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" moves stuff to bookshelf at "..minetest.pos_to_string(pos))
|
||||
end,
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" takes stuff from bookshelf at "..minetest.pos_to_string(pos))
|
||||
end,
|
||||
after_dig_node = drop_content,
|
||||
on_blast = on_blast,
|
||||
on_rightclick = bookshelf_gui,
|
||||
on_destruct = close_gui,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
name = mcl_books
|
||||
author = celeron55
|
||||
description = Books mod for MCL2
|
||||
depends = mcl_util, mcl_formspec
|
||||
optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye, mcl_colors
|
||||
|
|
|
@ -390,7 +390,7 @@ minetest.register_tool("mcl_fishing:fishing_rod", {
|
|||
_doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"),
|
||||
groups = { tool=1, fishing_rod=1, enchantability=1 },
|
||||
inventory_image = "mcl_fishing_fishing_rod.png",
|
||||
wield_image = "mcl_fishing_fishing_rod.png^[transformR270",
|
||||
wield_image = "mcl_fishing_fishing_rod.png^[transformFY^[transformR90",
|
||||
wield_scale = { x = 1.5, y = 1.5, z = 1 },
|
||||
stack_max = 1,
|
||||
on_place = fish,
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 359 B |
|
@ -177,15 +177,27 @@ local function drop_grindstone_items(pos, meta)
|
|||
end
|
||||
end
|
||||
|
||||
local node_box = {
|
||||
type = "fixed",
|
||||
-- created with nodebox editor
|
||||
fixed = {
|
||||
{-0.25, -0.25, -0.375, 0.25, 0.5, 0.375},
|
||||
{-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875},
|
||||
{0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875},
|
||||
{0.25, -0.5, -0.125, 0.375, -0.0625, 0.125},
|
||||
{-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125},
|
||||
}
|
||||
}
|
||||
|
||||
minetest.register_node("mcl_grindstone:grindstone", {
|
||||
description = S("Grindstone"),
|
||||
_tt_help = S("Used to disenchant/fix tools"),
|
||||
_doc_items_longdesc = S("Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station."),
|
||||
_doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.").."\n"..
|
||||
S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n"..
|
||||
S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n"..
|
||||
S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n"..
|
||||
S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."),
|
||||
S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n"..
|
||||
S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n"..
|
||||
S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n"..
|
||||
S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."),
|
||||
tiles = {
|
||||
"grindstone_top.png",
|
||||
"grindstone_top.png",
|
||||
|
@ -196,17 +208,7 @@ minetest.register_node("mcl_grindstone:grindstone", {
|
|||
},
|
||||
drawtype = "nodebox",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
-- created with nodebox editor
|
||||
fixed = {
|
||||
{-0.25, -0.25, -0.375, 0.25, 0.5, 0.375},
|
||||
{-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875},
|
||||
{0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875},
|
||||
{0.25, -0.5, -0.125, 0.375, -0.0625, 0.125},
|
||||
{-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125},
|
||||
}
|
||||
},
|
||||
node_box = node_box,
|
||||
selection_box = node_box,
|
||||
collision_box = node_box,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
|
|
|
@ -227,6 +227,7 @@ filled_wield_def.drawtype = "mesh"
|
|||
filled_wield_def.node_placement_prediction = ""
|
||||
filled_wield_def.range = minetest.registered_items[""].range
|
||||
filled_wield_def.on_place = mcl_util.call_on_rightclick
|
||||
filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map"
|
||||
|
||||
for _, texture in pairs(mcl_skins.list) do
|
||||
local def = table.copy(filled_wield_def)
|
||||
|
|
|
@ -321,7 +321,7 @@ minetest.register_tool("mcl_mobitems:carrot_on_a_stick", {
|
|||
_tt_help = S("Lets you ride a saddled pig"),
|
||||
_doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."),
|
||||
_doc_items_usagehelp = S("Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick."),
|
||||
wield_image = "mcl_mobitems_carrot_on_a_stick.png",
|
||||
wield_image = "mcl_mobitems_carrot_on_a_stick.png^[transformFY^[transformR90",
|
||||
inventory_image = "mcl_mobitems_carrot_on_a_stick.png",
|
||||
groups = { transport = 1 },
|
||||
_mcl_toollike_wield = true,
|
||||
|
|
|
@ -31,12 +31,12 @@ minetest.register_tool("mcl_shields:shield", {
|
|||
shield = 1,
|
||||
weapon = 1,
|
||||
enchantability = -1,
|
||||
no_wieldview = 1,
|
||||
offhand_item = 1,
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
_repair_material = "group:wood",
|
||||
wield_scale = vector.new(2, 2, 2),
|
||||
_mcl_wieldview_item = "",
|
||||
})
|
||||
|
||||
local function wielded_item(obj, i)
|
||||
|
@ -438,7 +438,6 @@ for _, colortab in pairs(mcl_banners.colors) do
|
|||
shield = 1,
|
||||
weapon = 1,
|
||||
enchantability = -1,
|
||||
no_wieldview = 1,
|
||||
not_in_creative_inventory = 1,
|
||||
offhand_item = 1,
|
||||
},
|
||||
|
@ -446,6 +445,7 @@ for _, colortab in pairs(mcl_banners.colors) do
|
|||
_repair_material = "group:wood",
|
||||
wield_scale = vector.new(2, 2, 2),
|
||||
_shield_color = colortab[4],
|
||||
_mcl_wieldview_item = "",
|
||||
})
|
||||
|
||||
local banner = "mcl_banners:banner_item_" .. color
|
||||
|
|
|
@ -7,19 +7,15 @@ mcl_smithing_table = {}
|
|||
|
||||
-- Function to upgrade diamond tool/armor to netherite tool/armor
|
||||
function mcl_smithing_table.upgrade_item(itemstack)
|
||||
itemstack = ItemStack(itemstack) -- Copy the stack
|
||||
|
||||
local def = itemstack:get_definition()
|
||||
|
||||
if not def or not def._mcl_upgradable then
|
||||
return
|
||||
end
|
||||
|
||||
local itemname = itemstack:get_name()
|
||||
local upgrade_item = itemname:gsub("diamond", "netherite")
|
||||
|
||||
local upgrade_item = def._mcl_upgrade_item or itemname:gsub("diamond", "netherite")
|
||||
|
||||
if upgrade_item == itemname then
|
||||
if def._mcl_upgrade_item and upgrade_item == itemname then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ mcl_structures.register_structure("pillager_outpost",{
|
|||
flags = "place_center_x, place_center_z",
|
||||
solid_ground = true,
|
||||
make_foundation = true,
|
||||
sidelen = 18,
|
||||
sidelen = 23,
|
||||
y_offset = 0,
|
||||
chunk_probability = 600,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
|
|
|
@ -33,21 +33,20 @@ minetest.register_on_dieplayer(function(player)
|
|||
end
|
||||
local listname = mcl_death_drop.registered_dropped_lists[l].listname
|
||||
local drop = mcl_death_drop.registered_dropped_lists[l].drop
|
||||
local dropspots = minetest.find_nodes_in_area(vector.offset(pos,-3,0,-3),vector.offset(pos,3,0,3),{"air"})
|
||||
if #dropspots == 0 then
|
||||
table.insert(dropspots,pos)
|
||||
end
|
||||
if inv then
|
||||
for i, stack in ipairs(inv:get_list(listname)) do
|
||||
local x = random(0, 9)/3
|
||||
local z = random(0, 9)/3
|
||||
pos.x = pos.x + x
|
||||
pos.z = pos.z + z
|
||||
local p = vector.offset(dropspots[math.random(#dropspots)],math.random()-0.5,math.random()-0.5,math.random()-0.5)
|
||||
if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then
|
||||
local def = minetest.registered_items[stack:get_name()]
|
||||
if def and def.on_drop then
|
||||
stack = def.on_drop(stack, player, pos)
|
||||
stack = def.on_drop(stack, player, p)
|
||||
end
|
||||
minetest.add_item(pos, stack)
|
||||
minetest.add_item(p, stack)
|
||||
end
|
||||
pos.x = pos.x - x
|
||||
pos.z = pos.z - z
|
||||
end
|
||||
inv:set_list(listname, {})
|
||||
end
|
||||
|
|
|
@ -103,10 +103,6 @@ function mcl_player.player_set_armor(player, texture)
|
|||
set_texture(player, 2, texture)
|
||||
end
|
||||
|
||||
function mcl_player.player_set_wielditem(player, texture)
|
||||
set_texture(player, 3, texture)
|
||||
end
|
||||
|
||||
function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)
|
||||
local name = player:get_player_name()
|
||||
local model = player_model[name]
|
||||
|
|
|
@ -359,15 +359,17 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
|
||||
if wielded_def and wielded_def._mcl_toollike_wield then
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0))
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,4.7,3.1), vector.new(-90,225,90))
|
||||
elseif string.find(wielded:get_name(), "mcl_bows:bow") then
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20))
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(1,4,0), vector.new(90,130,115))
|
||||
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(64,90,0))
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,73))
|
||||
elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(90,90,0))
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,45))
|
||||
elseif wielded_def.inventory_image == "" then
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,6,2), vector.new(180,-45,0))
|
||||
else
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90))
|
||||
set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.3,2), vector.new(90,0,0))
|
||||
end
|
||||
|
||||
-- controls right and left arms pitch when shooting a bow or blocking
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
[mod] visible wielded items [wieldview]
|
||||
[mod] visible wielded items [mcl_wieldview]
|
||||
=======================================
|
||||
|
||||
Makes hand wielded items visible to other players.
|
||||
|
||||
default settings: [minetest.conf]
|
||||
|
||||
# Set number of seconds between visible wielded item updates.
|
||||
wieldview_update_time = 2
|
||||
|
||||
# Show nodes as tiles, disabled by default
|
||||
wieldview_node_tiles = false
|
||||
|
||||
|
||||
Info for modders
|
||||
################
|
||||
|
||||
Wield image transformation: To apply a simple transformation to the item in
|
||||
hand, add the group “wieldview_transform” to the item definition. The group
|
||||
rating equals one of the numbers used for the [transform texture modifier
|
||||
of the Lua API.
|
||||
Register an item with the property "_mcl_wieldview_item" to change the third person wield view appearance of the item.
|
||||
"_mcl_wieldview_item" should be set to an item name that will be shown by the wield view instead of the item.
|
||||
If you use an empty string, nothing will be shown.
|
||||
|
||||
|
|
|
@ -1,126 +1,64 @@
|
|||
local get_connected_players = minetest.get_connected_players
|
||||
local get_item_group = minetest.get_item_group
|
||||
|
||||
mcl_wieldview = {
|
||||
players = {}
|
||||
}
|
||||
|
||||
function mcl_wieldview.get_item_texture(itemname)
|
||||
if itemname == "" or minetest.get_item_group(itemname, "no_wieldview") ~= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local def = minetest.registered_items[itemname]
|
||||
if not def then
|
||||
return
|
||||
end
|
||||
|
||||
local inv_image = def.inventory_image
|
||||
if inv_image == "" then
|
||||
return
|
||||
end
|
||||
|
||||
local texture = inv_image
|
||||
|
||||
local transform = get_item_group(itemname, "wieldview_transform")
|
||||
if transform then
|
||||
-- This actually works with groups ratings because transform1, transform2, etc.
|
||||
-- have meaning and transform0 is used for identidy, so it can be ignored
|
||||
texture = texture .. "^[transform" .. transform
|
||||
end
|
||||
|
||||
return texture
|
||||
end
|
||||
|
||||
function mcl_wieldview.update_wielded_item(player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local itemstack = player:get_wielded_item()
|
||||
local itemname = itemstack:get_name()
|
||||
|
||||
local def = mcl_wieldview.players[player]
|
||||
|
||||
if def.item == itemname then
|
||||
return
|
||||
end
|
||||
|
||||
def.item = itemname
|
||||
def.texture = mcl_wieldview.get_item_texture(itemname) or "blank.png"
|
||||
|
||||
mcl_player.player_set_wielditem(player, def.texture)
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_wieldview.players[player] = {item = "", texture = "blank.png"}
|
||||
|
||||
minetest.after(0, function()
|
||||
if not player:is_player() then
|
||||
return
|
||||
end
|
||||
|
||||
mcl_wieldview.update_wielded_item(player)
|
||||
|
||||
local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode")
|
||||
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
|
||||
itementity:get_luaentity().wielder = player
|
||||
end)
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
mcl_wieldview.players[player] = nil
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
local players = get_connected_players()
|
||||
for i = 1, #players do
|
||||
mcl_wieldview.update_wielded_item(players[i])
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_entity("mcl_wieldview:wieldnode", {
|
||||
minetest.register_entity("mcl_wieldview:wieldview", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
visual = "wielditem",
|
||||
physical = false,
|
||||
textures = {""},
|
||||
automatic_rotate = 1.5,
|
||||
is_visible = true,
|
||||
is_visible = false,
|
||||
pointable = false,
|
||||
collide_with_objects = false,
|
||||
static_save = false,
|
||||
collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
visual_size = {x = 0.21, y = 0.21},
|
||||
},
|
||||
|
||||
itemstring = "",
|
||||
|
||||
on_step = function(self)
|
||||
if self.wielder:is_player() then
|
||||
local def = mcl_wieldview.players[self.wielder]
|
||||
local itemstring = def.item
|
||||
|
||||
if self.itemstring ~= itemstring then
|
||||
local itemdef = minetest.registered_items[itemstring]
|
||||
self.object:set_properties({glow = itemdef and itemdef.light_source or 0})
|
||||
|
||||
-- wield item as cubic
|
||||
if def.texture == "blank.png" then
|
||||
self.object:set_properties({textures = {itemstring}})
|
||||
-- wield item as flat
|
||||
else
|
||||
self.object:set_properties({textures = {""}})
|
||||
end
|
||||
|
||||
if minetest.get_item_group(itemstring, "no_wieldview") ~= 0 then
|
||||
self.object:set_properties({textures = {""}})
|
||||
end
|
||||
|
||||
self.itemstring = itemstring
|
||||
end
|
||||
else
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
}
|
||||
})
|
||||
|
||||
local wieldview_luaentites = {}
|
||||
|
||||
local function update_wieldview_entity(player)
|
||||
local luaentity = wieldview_luaentites[player]
|
||||
if luaentity and luaentity.object:get_yaw() then
|
||||
local item = player:get_wielded_item():get_name()
|
||||
|
||||
if item == luaentity._item then return end
|
||||
|
||||
luaentity._item = item
|
||||
|
||||
local def = player:get_wielded_item():get_definition()
|
||||
if def and def._mcl_wieldview_item then
|
||||
item = def._mcl_wieldview_item
|
||||
end
|
||||
|
||||
local item_def = minetest.registered_items[item]
|
||||
luaentity.object:set_properties({
|
||||
glow = item_def and item_def.light_source or 0,
|
||||
wield_item = item,
|
||||
is_visible = item ~= ""
|
||||
})
|
||||
else
|
||||
-- If the player is running through an unloaded area,
|
||||
-- the wieldview entity will sometimes get unloaded.
|
||||
-- This code path is also used to initalize the wieldview.
|
||||
-- Creating entites from minetest.register_on_joinplayer
|
||||
-- is unreliable as of Minetest 5.6
|
||||
local obj_ref = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldview")
|
||||
if not obj_ref then return end
|
||||
obj_ref:set_attach(player, "Wield_Item")
|
||||
--obj_ref:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 45, 90))
|
||||
wieldview_luaentites[player] = obj_ref:get_luaentity()
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
if wieldview_luaentites[player] then
|
||||
wieldview_luaentites[player].object:remove()
|
||||
end
|
||||
wieldview_luaentites[player] = nil
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local players = minetest.get_connected_players()
|
||||
for i, player in pairs(players) do
|
||||
update_wieldview_entity(player)
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_wieldview
|
||||
author = stujones11
|
||||
description = Makes hand wielded items visible to other players.
|
||||
depends = mcl_player
|
||||
depends = mcl_armor, mcl_playerplus
|
||||
|
|
Loading…
Reference in New Issue