forked from VoxeLibre/VoxeLibre
Compare commits
63 Commits
master
...
master+nix
Author | SHA1 | Date |
---|---|---|
nixnoxus | 7bf2e63b06 | |
nixnoxus | 3edc1728ba | |
nixnoxus | 9809c627dc | |
nixnoxus | b37a1821fc | |
nixnoxus | e9d9959cbd | |
nixnoxus | 8f7f1d2bfc | |
nixnoxus | 738a1bf13a | |
nixnoxus | 3e4474b8d8 | |
nixnoxus | 4f99ce0af5 | |
nixnoxus | 734af602cf | |
nixnoxus | 1987c3732a | |
nixnoxus | 426ba50964 | |
nixnoxus | 99b32ca68e | |
nixnoxus | 88d6e50733 | |
nixnoxus | 2df570e275 | |
nixnoxus | a1b2d055fb | |
nixnoxus | 4a36e5eec9 | |
nixnoxus | 0235611487 | |
nixnoxus | 89c5365b36 | |
nixnoxus | fe88cca5d8 | |
nixnoxus | e3aa397198 | |
nixnoxus | 69dbbc7f94 | |
nixnoxus | 6d93ac8ef2 | |
nixnoxus | f4098cd504 | |
nixnoxus | 03cacfae1c | |
nixnoxus | 3b1d169669 | |
nixnoxus | 13272ccfb2 | |
nixnoxus | 7a2ce84a46 | |
nixnoxus | 3b19b760d1 | |
nixnoxus | 48c4ec3492 | |
nixnoxus | 7804459f96 | |
nixnoxus | 246e5352b6 | |
nixnoxus | 3f3f5d733c | |
nixnoxus | 8cb68c7325 | |
nixnoxus | edd46b97e6 | |
nixnoxus | ca6cbc0bda | |
nixnoxus | aa0a7ecc75 | |
nixnoxus | e660a38ee9 | |
nixnoxus | 8db0448bbe | |
nixnoxus | 703c5cd632 | |
nixnoxus | f903fe428a | |
nixnoxus | 7b39170839 | |
nixnoxus | 65cc03bc8f | |
nixnoxus | f54f838d26 | |
nixnoxus | 7e69f36307 | |
nixnoxus | ecd62dbba1 | |
nixnoxus | 8d0c3cd137 | |
nixnoxus | ae0e5f5eec | |
nixnoxus | 5076b44da1 | |
nixnoxus | 0d6db95a9e | |
nixnoxus | 078f5d760b | |
nixnoxus | 105a702931 | |
nixnoxus | 4dcffc0d5a | |
nixnoxus | 3870f38e87 | |
nixnoxus | dcefe14a46 | |
nixnoxus | 538cf4badb | |
nixnoxus | 497f1dcd80 | |
nixnoxus | 01cace413f | |
nixnoxus | e746556e09 | |
nixnoxus | 318deea5d6 | |
nixnoxus | 0e73f77148 | |
nixnoxus | da5f91b0f6 | |
nixnoxus | b70f7ac459 |
|
@ -135,3 +135,33 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||||
end
|
end
|
||||||
return {x=0, y=0, z=0}
|
return {x=0, y=0, z=0}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local plane_adjacents = {
|
||||||
|
vector.new(-1,0,0),
|
||||||
|
vector.new(1,0,0),
|
||||||
|
vector.new(0,0,-1),
|
||||||
|
vector.new(0,0,1),
|
||||||
|
}
|
||||||
|
|
||||||
|
function mcl_minecarts:get_start_direction(pos)
|
||||||
|
local dir
|
||||||
|
local i = 0
|
||||||
|
while (not dir and i < #plane_adjacents) do
|
||||||
|
i = i+1
|
||||||
|
local node = minetest.get_node_or_nil(vector.add(pos, plane_adjacents[i]))
|
||||||
|
if node ~= nil
|
||||||
|
and minetest.get_item_group(node.name, "rail") == 0
|
||||||
|
and minetest.get_item_group(node.name, "solid") == 1
|
||||||
|
and minetest.get_item_group(node.name, "opaque") == 1
|
||||||
|
then
|
||||||
|
dir = mcl_minecarts:check_front_up_down(pos, vector.multiply(plane_adjacents[i], -1), true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return dir
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_minecarts:set_velocity(obj, dir, factor)
|
||||||
|
obj._velocity = vector.multiply(dir, factor or 3)
|
||||||
|
obj._old_pos = nil
|
||||||
|
obj._punched = true
|
||||||
|
end
|
||||||
|
|
|
@ -241,9 +241,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self._velocity = vector.multiply(cart_dir, 3)
|
mcl_minecarts:set_velocity(self, cart_dir)
|
||||||
self._old_pos = nil
|
|
||||||
self._punched = true
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -300,9 +298,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
|
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
|
||||||
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
|
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
|
||||||
|
|
||||||
self._velocity = vector.multiply(cart_dir, f)
|
mcl_minecarts:set_velocity(self, cart_dir, f)
|
||||||
self._old_pos = nil
|
|
||||||
self._punched = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
cart.on_activate_by_rail = on_activate_by_rail
|
cart.on_activate_by_rail = on_activate_by_rail
|
||||||
|
@ -470,7 +466,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local dir, last_switch = nil, nil
|
local dir, last_switch, restart_pos = nil, nil, nil
|
||||||
if not pos then
|
if not pos then
|
||||||
pos = self.object:get_pos()
|
pos = self.object:get_pos()
|
||||||
end
|
end
|
||||||
|
@ -497,6 +493,9 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
minetest.swap_node(rou_pos, newnode)
|
minetest.swap_node(rou_pos, newnode)
|
||||||
mesecon.receptor_on(rou_pos)
|
mesecon.receptor_on(rou_pos)
|
||||||
end
|
end
|
||||||
|
if node.name == "mcl_minecarts:golden_rail_on" then
|
||||||
|
restart_pos = rou_pos
|
||||||
|
end
|
||||||
if node_old.name == "mcl_minecarts:detector_rail_on" then
|
if node_old.name == "mcl_minecarts:detector_rail_on" then
|
||||||
local newnode = {name="mcl_minecarts:detector_rail", param2 = node_old.param2}
|
local newnode = {name="mcl_minecarts:detector_rail", param2 = node_old.param2}
|
||||||
minetest.swap_node(rou_old, newnode)
|
minetest.swap_node(rou_old, newnode)
|
||||||
|
@ -647,6 +646,14 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
if update.pos then
|
if update.pos then
|
||||||
self.object:set_pos(pos)
|
self.object:set_pos(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- stopped on "mcl_minecarts:golden_rail_on"
|
||||||
|
if vector.equals(vel, {x=0, y=0, z=0}) and restart_pos then
|
||||||
|
local dir = mcl_minecarts:get_start_direction(restart_pos)
|
||||||
|
if dir then
|
||||||
|
mcl_minecarts:set_velocity(self, dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:get_staticdata()
|
function cart:get_staticdata()
|
||||||
|
@ -687,7 +694,15 @@ function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer)
|
||||||
if le then
|
if le then
|
||||||
le._railtype = railtype
|
le._railtype = railtype
|
||||||
end
|
end
|
||||||
local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
local cart_dir
|
||||||
|
if node.name == "mcl_minecarts:golden_rail_on" then
|
||||||
|
cart_dir = mcl_minecarts:get_start_direction(railpos)
|
||||||
|
end
|
||||||
|
if cart_dir then
|
||||||
|
mcl_minecarts:set_velocity(le, cart_dir)
|
||||||
|
else
|
||||||
|
cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
||||||
|
end
|
||||||
cart:set_yaw(minetest.dir_to_yaw(cart_dir))
|
cart:set_yaw(minetest.dir_to_yaw(cart_dir))
|
||||||
|
|
||||||
local pname = ""
|
local pname = ""
|
||||||
|
|
|
@ -112,6 +112,22 @@ register_rail("mcl_minecarts:golden_rail_on",
|
||||||
onstate = "mcl_minecarts:golden_rail_on",
|
onstate = "mcl_minecarts:golden_rail_on",
|
||||||
rules = rail_rules_long,
|
rules = rail_rules_long,
|
||||||
},
|
},
|
||||||
|
effector = {
|
||||||
|
action_on = function(pos, node)
|
||||||
|
local dir = mcl_minecarts:get_start_direction(pos)
|
||||||
|
if not dir then return end
|
||||||
|
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||||
|
for _, o in pairs(objs) do
|
||||||
|
local l = o:get_luaentity()
|
||||||
|
local v = o:get_velocity()
|
||||||
|
if l and string.sub(l.name, 1, 14) == "mcl_minecarts:"
|
||||||
|
and v and vector.equals(v, vector.zero())
|
||||||
|
then
|
||||||
|
mcl_minecarts:set_velocity(l, dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
drop = "mcl_minecarts:golden_rail",
|
drop = "mcl_minecarts:golden_rail",
|
||||||
},
|
},
|
||||||
|
|
|
@ -82,6 +82,7 @@ functions needed for the mob to work properly which contains the following:
|
||||||
|
|
||||||
'reach' is how far the mob can attack player when standing
|
'reach' is how far the mob can attack player when standing
|
||||||
nearby, default is 3 nodes.
|
nearby, default is 3 nodes.
|
||||||
|
'shoot_reach' is how far the mob can shoot, default is 16 nodes.
|
||||||
'docile_by_day' when true has mobs wandering around during daylight
|
'docile_by_day' when true has mobs wandering around during daylight
|
||||||
hours and only attacking player at night or when
|
hours and only attacking player at night or when
|
||||||
provoked.
|
provoked.
|
||||||
|
@ -128,7 +129,7 @@ functions needed for the mob to work properly which contains the following:
|
||||||
arrow/fireball appears on mob.
|
arrow/fireball appears on mob.
|
||||||
'specific_attack' has a table of entity names that mob can also attack
|
'specific_attack' has a table of entity names that mob can also attack
|
||||||
e.g. {"player", "mobs_animal:chicken"}.
|
e.g. {"player", "mobs_animal:chicken"}.
|
||||||
'runaway_from' contains a table with mob names to run away from, add
|
'runaway_from' contains a table with mob/node names to run away from, add
|
||||||
"player" to list to runaway from player also.
|
"player" to list to runaway from player also.
|
||||||
'pathfinding' set to 1 for mobs to use pathfinder feature to locate
|
'pathfinding' set to 1 for mobs to use pathfinder feature to locate
|
||||||
player, set to 2 so they can build/break also (only
|
player, set to 2 so they can build/break also (only
|
||||||
|
@ -263,6 +264,9 @@ functions needed for the mob to work properly which contains the following:
|
||||||
'noyaw' If true this mob will not automatically change yaw
|
'noyaw' If true this mob will not automatically change yaw
|
||||||
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
|
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
|
||||||
'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm.
|
'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm.
|
||||||
|
'avoid_from' contains a table with mob/node names to avoid from, add
|
||||||
|
"player" to list to avoid from player also.
|
||||||
|
|
||||||
|
|
||||||
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
|
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
|
||||||
|
|
||||||
|
@ -449,6 +453,16 @@ Create death particles at pos with the given collisionbox.
|
||||||
|
|
||||||
mcl_mobs.spawn(pos,name/entity name)
|
mcl_mobs.spawn(pos,name/entity name)
|
||||||
|
|
||||||
|
|
||||||
|
mcl_mobs:is_object_in_view(object_list, object_range, node_range, turn_around)
|
||||||
|
|
||||||
|
Returns 'true' if an object (mob or node) is in the field of view.
|
||||||
|
|
||||||
|
'object_list' list of mob and/or node names
|
||||||
|
'object_range' maximum distance to a mob from object_list
|
||||||
|
'node_range' maximum distance to a node from object_list
|
||||||
|
'turn_around' true or false
|
||||||
|
|
||||||
Making Arrows
|
Making Arrows
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ function mob_class:toggle_sit(clicker,p)
|
||||||
particle = "mobs_mc_wolf_icon_roam.png"
|
particle = "mobs_mc_wolf_icon_roam.png"
|
||||||
self.order = "roam"
|
self.order = "roam"
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
self.walk_chance = default_walk_chance
|
self.walk_chance = 50
|
||||||
self.jump = true
|
self.jump = true
|
||||||
self:set_animation("stand")
|
self:set_animation("stand")
|
||||||
-- TODO: Add sitting model
|
-- TODO: Add sitting model
|
||||||
|
|
|
@ -360,7 +360,7 @@ function mob_class:monster_attack()
|
||||||
player = obj.object
|
player = obj.object
|
||||||
name = obj.name or ""
|
name = obj.name or ""
|
||||||
end
|
end
|
||||||
if obj and obj.type == self.type and obj.passive == false and obj.state == "attack" and obj.attack then
|
if obj and obj.type == self.type and obj.passive == false and obj.state == "attack" and obj.attack and self.object ~= obj.attack then
|
||||||
table.insert(blacklist_attack, obj.attack)
|
table.insert(blacklist_attack, obj.attack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -388,6 +388,7 @@ function mob_class:monster_attack()
|
||||||
|
|
||||||
-- find specific mob to attack, failing that attack player/npc/animal
|
-- find specific mob to attack, failing that attack player/npc/animal
|
||||||
if specific_attack(self.specific_attack, name)
|
if specific_attack(self.specific_attack, name)
|
||||||
|
and self.object ~= player
|
||||||
and (type == "player" or ( type == "npc" and self.attack_npcs )
|
and (type == "player" or ( type == "npc" and self.attack_npcs )
|
||||||
or (type == "animal" and self.attack_animals == true)
|
or (type == "animal" and self.attack_animals == true)
|
||||||
or (self.extra_hostile and not self.attack_exception(player))) then
|
or (self.extra_hostile and not self.attack_exception(player))) then
|
||||||
|
@ -1153,9 +1154,9 @@ function mob_class:do_states_attack (dtime)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif self.attack_type == "shoot"
|
elseif dist <= self.shoot_reach and (self.attack_type == "shoot"
|
||||||
or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 1)
|
or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 1)
|
||||||
or (self.attack_type == "dogshoot" and (dist > self.reach or dist < self.avoid_distance and self.shooter_avoid_enemy) and self:dogswitch() == 0) then
|
or (self.attack_type == "dogshoot" and (dist > self.reach or dist < self.avoid_distance and self.shooter_avoid_enemy) and self:dogswitch() == 0)) then
|
||||||
|
|
||||||
p.y = p.y - .5
|
p.y = p.y - .5
|
||||||
s.y = s.y + .5
|
s.y = s.y + .5
|
||||||
|
|
|
@ -229,6 +229,7 @@ function mcl_mobs.register_mob(name, def)
|
||||||
health = 0,
|
health = 0,
|
||||||
frame_speed_multiplier = 1,
|
frame_speed_multiplier = 1,
|
||||||
reach = def.reach or 3,
|
reach = def.reach or 3,
|
||||||
|
shoot_reach = def.shoot_reach or def.view_range or 16,
|
||||||
htimer = 0,
|
htimer = 0,
|
||||||
texture_list = def.textures,
|
texture_list = def.textures,
|
||||||
child_texture = def.child_texture,
|
child_texture = def.child_texture,
|
||||||
|
@ -289,6 +290,7 @@ function mcl_mobs.register_mob(name, def)
|
||||||
noyaw = def.noyaw or false,
|
noyaw = def.noyaw or false,
|
||||||
particlespawners = def.particlespawners,
|
particlespawners = def.particlespawners,
|
||||||
spawn_check = def.spawn_check,
|
spawn_check = def.spawn_check,
|
||||||
|
avoid_from = def.avoid_from,
|
||||||
-- End of MCL2 extensions
|
-- End of MCL2 extensions
|
||||||
on_spawn = def.on_spawn,
|
on_spawn = def.on_spawn,
|
||||||
on_blast = def.on_blast or function(self,damage)
|
on_blast = def.on_blast or function(self,damage)
|
||||||
|
|
|
@ -509,6 +509,81 @@ function mob_class:do_jump()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function in_list(list, what)
|
||||||
|
return type(list) == "table" and table.indexof(list, what) ~= -1
|
||||||
|
end
|
||||||
|
|
||||||
|
function mob_class:is_object_in_view(object_list, object_range, node_range, turn_around)
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
local min_dist = object_range + 1
|
||||||
|
local objs = minetest.get_objects_inside_radius(s, object_range)
|
||||||
|
local object_pos = nil
|
||||||
|
|
||||||
|
for n = 1, #objs do
|
||||||
|
local name = ""
|
||||||
|
local object = objs[n]
|
||||||
|
|
||||||
|
if object:is_player() then
|
||||||
|
if not (mcl_mobs.invis[ object:get_player_name() ]
|
||||||
|
or self.owner == object:get_player_name()
|
||||||
|
or (not self:object_in_range(object))) then
|
||||||
|
name = "player"
|
||||||
|
if not (name ~= self.name
|
||||||
|
and in_list(object_list, name)) then
|
||||||
|
local item = object:get_wielded_item()
|
||||||
|
name = item:get_name() or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local obj = object:get_luaentity()
|
||||||
|
|
||||||
|
if obj then
|
||||||
|
object = obj.object
|
||||||
|
name = obj.name or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- find specific mob to avoid or runaway from
|
||||||
|
if name ~= "" and name ~= self.name
|
||||||
|
and in_list(object_list, name) then
|
||||||
|
|
||||||
|
local p = object:get_pos()
|
||||||
|
local dist = vector.distance(p, s)
|
||||||
|
|
||||||
|
-- choose closest player/mob to avoid or runaway from
|
||||||
|
if dist < min_dist
|
||||||
|
-- aim higher to make looking up hills more realistic
|
||||||
|
and self:line_of_sight(vector.offset(s, 0,1,0), vector.offset(p, 0,1,0)) == true then
|
||||||
|
min_dist = dist
|
||||||
|
object_pos = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not object_pos then
|
||||||
|
|
||||||
|
-- find specific node to avoid or runaway from
|
||||||
|
local p = minetest.find_node_near(s, node_range, object_list, true)
|
||||||
|
local dist = p and vector.distance(p, s)
|
||||||
|
if dist and dist < min_dist
|
||||||
|
and self:line_of_sight(s, p) == true then
|
||||||
|
min_dist = dist
|
||||||
|
object_pos = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_pos and turn_around then
|
||||||
|
|
||||||
|
local vec = vector.subtract(object_pos, s)
|
||||||
|
local yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate
|
||||||
|
if object_pos.x > s.x then yaw = yaw + math.pi end
|
||||||
|
|
||||||
|
yaw = self:set_yaw(yaw, 4)
|
||||||
|
end
|
||||||
|
|
||||||
|
return object_pos ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
-- should mob follow what I'm holding ?
|
-- should mob follow what I'm holding ?
|
||||||
function mob_class:follow_holding(clicker)
|
function mob_class:follow_holding(clicker)
|
||||||
if self.nofollow then return false end
|
if self.nofollow then return false end
|
||||||
|
@ -526,15 +601,9 @@ function mob_class:follow_holding(clicker)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
-- multiple items
|
-- multiple items
|
||||||
elseif t == "table" then
|
elseif t == "table" and in_list(self.follow, item:get_name()) then
|
||||||
|
|
||||||
for no = 1, #self.follow do
|
|
||||||
|
|
||||||
if self.follow[no] == item:get_name() then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -593,104 +662,14 @@ function mob_class:replace_node(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- specific runaway
|
|
||||||
local specific_runaway = function(list, what)
|
|
||||||
if type(list) ~= "table" then
|
|
||||||
list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- no list so do not run
|
|
||||||
if list == nil then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- found entity on list to attack?
|
|
||||||
for no = 1, #list do
|
|
||||||
|
|
||||||
if list[no] == what then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- find someone to runaway from
|
-- find someone to runaway from
|
||||||
function mob_class:check_runaway_from()
|
function mob_class:check_runaway_from()
|
||||||
if not self.runaway_from and self.state ~= "flop" then
|
if not self.runaway_from and self.state ~= "flop" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = self.object:get_pos()
|
if self:is_object_in_view(self.runaway_from, self.view_range, self.view_range / 2, true) then
|
||||||
local p, sp, dist
|
self.shaking = self.shaking or 5
|
||||||
local player, obj, min_player
|
|
||||||
local type, name = "", ""
|
|
||||||
local min_dist = self.view_range + 1
|
|
||||||
local objs = minetest.get_objects_inside_radius(s, self.view_range)
|
|
||||||
|
|
||||||
for n = 1, #objs do
|
|
||||||
|
|
||||||
if objs[n]:is_player() then
|
|
||||||
|
|
||||||
if mcl_mobs.invis[ objs[n]:get_player_name() ]
|
|
||||||
or self.owner == objs[n]:get_player_name()
|
|
||||||
or (not self:object_in_range(objs[n])) then
|
|
||||||
type = ""
|
|
||||||
else
|
|
||||||
player = objs[n]
|
|
||||||
type = "player"
|
|
||||||
name = "player"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
obj = objs[n]:get_luaentity()
|
|
||||||
|
|
||||||
if obj then
|
|
||||||
player = obj.object
|
|
||||||
type = obj.type
|
|
||||||
name = obj.name or ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- find specific mob to runaway from
|
|
||||||
if name ~= "" and name ~= self.name
|
|
||||||
and specific_runaway(self.runaway_from, name) then
|
|
||||||
|
|
||||||
p = player:get_pos()
|
|
||||||
sp = s
|
|
||||||
|
|
||||||
-- aim higher to make looking up hills more realistic
|
|
||||||
p.y = p.y + 1
|
|
||||||
sp.y = sp.y + 1
|
|
||||||
|
|
||||||
dist = vector.distance(p, s)
|
|
||||||
|
|
||||||
|
|
||||||
-- choose closest player/mpb to runaway from
|
|
||||||
if dist < min_dist
|
|
||||||
and self:line_of_sight(sp, p, 2) == true then
|
|
||||||
min_dist = dist
|
|
||||||
min_player = player
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if min_player then
|
|
||||||
|
|
||||||
local lp = player:get_pos()
|
|
||||||
local vec = {
|
|
||||||
x = lp.x - s.x,
|
|
||||||
y = lp.y - s.y,
|
|
||||||
z = lp.z - s.z
|
|
||||||
}
|
|
||||||
|
|
||||||
local yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate
|
|
||||||
|
|
||||||
if lp.x > s.x then
|
|
||||||
yaw = yaw + math.pi
|
|
||||||
end
|
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 4)
|
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.runaway_timer = 3
|
self.runaway_timer = 3
|
||||||
self.following = nil
|
self.following = nil
|
||||||
|
@ -914,23 +893,20 @@ function mob_class:do_states_walk()
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- A danger is near but mob is not inside
|
|
||||||
else
|
|
||||||
|
|
||||||
-- Randomly turn
|
|
||||||
if math.random(1, 100) <= 30 then
|
|
||||||
yaw = yaw + math.random(-0.5, 0.5)
|
|
||||||
yaw = self:set_yaw( yaw, 8)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 8)
|
if not is_in_danger then
|
||||||
|
local distance = self.avoid_distance or self.view_range / 2
|
||||||
|
-- find specific node to avoid
|
||||||
|
if self:is_object_in_view(self.avoid_from, distance, distance, true) then
|
||||||
|
self.shaking = self.shaking or 2
|
||||||
|
self:set_velocity(self.walk_velocity)
|
||||||
-- otherwise randomly turn
|
-- otherwise randomly turn
|
||||||
elseif math.random(1, 100) <= 30 then
|
elseif math.random(1, 100) <= 30 then
|
||||||
yaw = yaw + math.random(-0.5, 0.5)
|
yaw = yaw + math.random(-0.5, 0.5)
|
||||||
yaw = self:set_yaw( yaw, 8)
|
yaw = self:set_yaw(yaw, 8)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stand for great fall or danger or fence in front
|
-- stand for great fall or danger or fence in front
|
||||||
|
@ -938,6 +914,7 @@ function mob_class:do_states_walk()
|
||||||
if is_in_danger then
|
if is_in_danger then
|
||||||
cliff_or_danger = self:is_at_cliff_or_danger()
|
cliff_or_danger = self:is_at_cliff_or_danger()
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.facing_fence == true
|
if self.facing_fence == true
|
||||||
or cliff_or_danger
|
or cliff_or_danger
|
||||||
or math.random(1, 100) <= 30 then
|
or math.random(1, 100) <= 30 then
|
||||||
|
@ -1086,6 +1063,12 @@ function mob_class:check_smooth_rotation(dtime)
|
||||||
self.delay = self.delay - 1
|
self.delay = self.delay - 1
|
||||||
if self.shaking then
|
if self.shaking then
|
||||||
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
|
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
|
||||||
|
if type(self.shaking) == "number" then
|
||||||
|
self.shaking = self.shaking - dtime
|
||||||
|
if self.shaking <= 0 then
|
||||||
|
self.shaking = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
self.object:set_yaw(yaw)
|
self.object:set_yaw(yaw)
|
||||||
--self:update_roll()
|
--self:update_roll()
|
||||||
|
|
|
@ -40,6 +40,17 @@ local hoglin = {
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 2.8,
|
run_velocity = 2.8,
|
||||||
|
avoid_from = {
|
||||||
|
"mcl_crimson:warped_fungus",
|
||||||
|
"mcl_flowerpots:flower_pot_warped_fungus",
|
||||||
|
"mcl_portals:portal",
|
||||||
|
"mcl_beds:respawn_anchor",
|
||||||
|
"mcl_beds:respawn_anchor_charged_1",
|
||||||
|
"mcl_beds:respawn_anchor_charged_2",
|
||||||
|
"mcl_beds:respawn_anchor_charged_3",
|
||||||
|
"mcl_beds:respawn_anchor_charged_4",
|
||||||
|
},
|
||||||
|
follow = {"mcl_crimson:crimson_fungus"},
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs_mcitems:leather",
|
{name = "mobs_mcitems:leather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
|
@ -87,9 +98,26 @@ local hoglin = {
|
||||||
attack_animals = true,
|
attack_animals = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mobs.register_mob("mobs_mc:hoglin", hoglin)
|
|
||||||
|
|
||||||
local zoglin = table.copy(hoglin)
|
local zoglin = table.copy(hoglin)
|
||||||
|
hoglin.on_rightclick = function(self, clicker)
|
||||||
|
-- local item = clicker:get_wielded_item()
|
||||||
|
if self:feed_tame(clicker, 1, true, false) then return end
|
||||||
|
-- if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
end
|
||||||
|
hoglin.on_breed = function(parent1, parent2)
|
||||||
|
local pos = parent1.object:get_pos()
|
||||||
|
local child = mcl_mobs.spawn_child(pos, parent1.name)
|
||||||
|
if child then
|
||||||
|
local ent_c = child:get_luaentity()
|
||||||
|
-- ent_c.tamed = true
|
||||||
|
ent_c.owner = parent1.owner
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
mcl_mobs.register_mob("mobs_mc:hoglin", hoglin)
|
||||||
|
|
||||||
zoglin.description = S("Zoglin")
|
zoglin.description = S("Zoglin")
|
||||||
zoglin.fire_resistant = 1
|
zoglin.fire_resistant = 1
|
||||||
zoglin.textures = {"extra_mobs_zoglin.png"}
|
zoglin.textures = {"extra_mobs_zoglin.png"}
|
||||||
|
|
|
@ -112,6 +112,10 @@ mcl_mobs.register_mob("mobs_mc:llama", {
|
||||||
},
|
},
|
||||||
follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" },
|
follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" },
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
|
attack_animals = true,
|
||||||
|
damage = 1,
|
||||||
|
shoot_reach = 5,
|
||||||
|
specific_attack = { "mobs_mc:wolf" },
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
-- set needed values if not already present
|
-- set needed values if not already present
|
||||||
|
|
|
@ -16,6 +16,13 @@ local trading_items = {
|
||||||
{ itemstring = "mcl_throwing:ender_pearl", amount_min = 2, amount_max = 6 },
|
{ itemstring = "mcl_throwing:ender_pearl", amount_min = 2, amount_max = 6 },
|
||||||
{ itemstring = "mcl_potions:fire_resistance", amount_min = 1, amount_max = 1 },
|
{ itemstring = "mcl_potions:fire_resistance", amount_min = 1, amount_max = 1 },
|
||||||
{ itemstring = "mcl_potions:fire_resistance_splash", amount_min = 1, amount_max = 1 },
|
{ itemstring = "mcl_potions:fire_resistance_splash", amount_min = 1, amount_max = 1 },
|
||||||
|
{ itemstring = "mcl_enchanting:book_enchanted", amount_min = 1, amount_max = 1 },
|
||||||
|
{ itemstring = "mcl_armor:boots_iron_enchanted", amount_min = 1, amount_max = 1 },
|
||||||
|
{ itemstring = "mcl_blackstone:blackstone", amount_min = 8, amount_max = 16 },
|
||||||
|
{ itemstring = "mcl_bows:arrow", amount_min = 6, amount_max = 12 },
|
||||||
|
{ itemstring = "mcl_core:crying_obsidian", amount_min = 1, amount_max = 1 },
|
||||||
|
{ itemstring = "mcl_fire:fire_charge", amount_min = 1, amount_max = 1 },
|
||||||
|
--{ itemstring = "FIXME:spectral_arrow", amount_min = 6, amount_max = 12 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local S = minetest.get_translator("mobs_mc")
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
@ -142,14 +149,18 @@ local piglin = {
|
||||||
local c_pos = self.object:get_pos()
|
local c_pos = self.object:get_pos()
|
||||||
if c_pos then
|
if c_pos then
|
||||||
self.what_traded = trading_items[math.random(#trading_items)]
|
self.what_traded = trading_items[math.random(#trading_items)]
|
||||||
for x = 1, math.random(self.what_traded.amount_min, self.what_traded.amount_max) do
|
local stack = ItemStack(self.what_traded.itemstring)
|
||||||
|
stack:set_count(math.random(self.what_traded.amount_min, self.what_traded.amount_max))
|
||||||
|
if mcl_enchanting.is_enchanted(self.what_traded.itemstring) then
|
||||||
|
local enchantment = "soul_speed"
|
||||||
|
mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(nil, 1, mcl_enchanting.enchantments[enchantment].max_level))
|
||||||
|
end
|
||||||
local p = c_pos
|
local p = c_pos
|
||||||
local nn=minetest.find_nodes_in_area_under_air(vector.offset(c_pos,-1,-1,-1),vector.offset(c_pos,1,1,1),{"group:solid"})
|
local nn=minetest.find_nodes_in_area_under_air(vector.offset(c_pos,-1,-1,-1),vector.offset(c_pos,1,1,1),{"group:solid"})
|
||||||
if nn and #nn > 0 then
|
if nn and #nn > 0 then
|
||||||
p = vector.offset(nn[math.random(#nn)],0,1,0)
|
p = vector.offset(nn[math.random(#nn)],0,1,0)
|
||||||
end
|
end
|
||||||
minetest.add_item(p, self.what_traded.itemstring)
|
minetest.add_item(p, stack)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,6 +42,7 @@ local rabbit = {
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3.7,
|
run_velocity = 3.7,
|
||||||
|
avoid_from = {"mobs_mc:wolf"},
|
||||||
follow_velocity = 1.1,
|
follow_velocity = 1.1,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
runaway = true,
|
runaway = true,
|
||||||
|
|
|
@ -46,6 +46,7 @@ local skeleton = {
|
||||||
},
|
},
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.0,
|
run_velocity = 2.0,
|
||||||
|
runaway_from = {"mobs_mc:wolf"},
|
||||||
damage = 2,
|
damage = 2,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
|
|
|
@ -44,6 +44,7 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
|
||||||
},
|
},
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.0,
|
run_velocity = 2.0,
|
||||||
|
runaway_from = {"mobs_mc:wolf"},
|
||||||
damage = 7,
|
damage = 7,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
|
|
|
@ -30,6 +30,8 @@ local strider = {
|
||||||
} },
|
} },
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
sounds = {
|
sounds = {
|
||||||
|
eat = "mobs_mc_animal_eat_generic",
|
||||||
|
distance = 16,
|
||||||
},
|
},
|
||||||
jump = true,
|
jump = true,
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -51,6 +53,7 @@ local strider = {
|
||||||
walk_start = 1,
|
walk_start = 1,
|
||||||
walk_end = 20,
|
walk_end = 20,
|
||||||
},
|
},
|
||||||
|
follow = { "mcl_crimson:warped_fungus" },
|
||||||
lava_damage = 0,
|
lava_damage = 0,
|
||||||
fire_damage = 0,
|
fire_damage = 0,
|
||||||
light_damage = 0,
|
light_damage = 0,
|
||||||
|
@ -67,8 +70,13 @@ local strider = {
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
if minetest.find_node_near(self.object:get_pos(), 2, {"mcl_core:lava_source","mcl_core:lava_flowing","mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) then
|
if minetest.find_node_near(self.object:get_pos(), 2, {"mcl_core:lava_source","mcl_core:lava_flowing","mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) then
|
||||||
|
if self.driver then
|
||||||
|
self.walk_velocity = 4
|
||||||
|
self.run_velocity = 8
|
||||||
|
else
|
||||||
self.walk_velocity = 2
|
self.walk_velocity = 2
|
||||||
self.run_velocity = 4
|
self.run_velocity = 4
|
||||||
|
end
|
||||||
self.base_texture[1] = "extra_mobs_strider.png"
|
self.base_texture[1] = "extra_mobs_strider.png"
|
||||||
self.shaking = false
|
self.shaking = false
|
||||||
else
|
else
|
||||||
|
@ -122,7 +130,7 @@ local strider = {
|
||||||
|
|
||||||
local wielditem = clicker:get_wielded_item()
|
local wielditem = clicker:get_wielded_item()
|
||||||
|
|
||||||
if wielditem:get_name() ~= "mcl_crimson:warped_fungus" then
|
if wielditem:get_name() == "mcl_crimson:warped_fungus" then
|
||||||
if self:feed_tame(clicker, 1, true, true) then return end
|
if self:feed_tame(clicker, 1, true, true) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -206,7 +214,7 @@ textures = { {
|
||||||
} }
|
} }
|
||||||
baby_strider.walk_velocity = 1.2
|
baby_strider.walk_velocity = 1.2
|
||||||
baby_strider.run_velocity = 2.4
|
baby_strider.run_velocity = 2.4
|
||||||
baby_strider.child = 1
|
baby_strider.child = true
|
||||||
|
|
||||||
mcl_mobs.register_mob("mobs_mc:baby_strider", baby_strider)
|
mcl_mobs.register_mob("mobs_mc:baby_strider", baby_strider)
|
||||||
|
|
||||||
|
|
|
@ -1989,6 +1989,17 @@ local trade_inventory = {
|
||||||
-- Otherwise, 20% chance to unlock if used freshly reset trade
|
-- Otherwise, 20% chance to unlock if used freshly reset trade
|
||||||
unlock_stuff = true
|
unlock_stuff = true
|
||||||
end
|
end
|
||||||
|
-- calculate xp based on the price
|
||||||
|
local emeralds = 0
|
||||||
|
if wanted1:get_name() == "mcl_core:emerald" then
|
||||||
|
emeralds = wanted1:get_count()
|
||||||
|
elseif wanted2:get_name() == "mcl_core:emerald" then
|
||||||
|
emeralds = wanted2:get_count()
|
||||||
|
else
|
||||||
|
local offered = inv:get_stack("offered", 1)
|
||||||
|
emeralds = offered:get_name() == "mcl_core:emerald" and offered:get_count() or 0
|
||||||
|
end
|
||||||
|
local xp = 2 + math.ceil(emeralds / (64/4)) -- 1..64 emeralds = 3..6 xp
|
||||||
local update_formspec = false
|
local update_formspec = false
|
||||||
if unlock_stuff then
|
if unlock_stuff then
|
||||||
-- First-time trade unlock all trades and unlock next trade tier
|
-- First-time trade unlock all trades and unlock next trade tier
|
||||||
|
@ -2000,6 +2011,7 @@ local trade_inventory = {
|
||||||
set_textures(trader)
|
set_textures(trader)
|
||||||
update_max_tradenum(trader)
|
update_max_tradenum(trader)
|
||||||
update_formspec = true
|
update_formspec = true
|
||||||
|
xp = xp + 5
|
||||||
end
|
end
|
||||||
for t=1, #trades do
|
for t=1, #trades do
|
||||||
trades[t].locked = false
|
trades[t].locked = false
|
||||||
|
@ -2010,6 +2022,7 @@ local trade_inventory = {
|
||||||
-- TODO: Replace by Regeneration I
|
-- TODO: Replace by Regeneration I
|
||||||
trader.health = math.min(trader.hp_max, trader.health + 4)
|
trader.health = math.min(trader.hp_max, trader.health + 4)
|
||||||
end
|
end
|
||||||
|
mcl_experience.add_xp(player, xp)
|
||||||
trade.trade_counter = trade.trade_counter + 1
|
trade.trade_counter = trade.trade_counter + 1
|
||||||
mcl_log("Trade counter is: ".. trade.trade_counter)
|
mcl_log("Trade counter is: ".. trade.trade_counter)
|
||||||
-- Semi-randomly lock trade for repeated trade (not if there's only 1 trade)
|
-- Semi-randomly lock trade for repeated trade (not if there's only 1 trade)
|
||||||
|
@ -2047,6 +2060,7 @@ local trade_inventory = {
|
||||||
if update_formspec then
|
if update_formspec then
|
||||||
show_trade_formspec(name, trader, tradenum)
|
show_trade_formspec(name, trader, tradenum)
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
minetest.log("error", "[mobs_mc] Player took item from trader output but player_trading_with or player_tradenum is nil!")
|
minetest.log("error", "[mobs_mc] Player took item from trader output but player_trading_with or player_tradenum is nil!")
|
||||||
end
|
end
|
||||||
|
|
|
@ -97,7 +97,16 @@ local wolf = {
|
||||||
jump = true,
|
jump = true,
|
||||||
attacks_monsters = true,
|
attacks_monsters = true,
|
||||||
attack_animals = true,
|
attack_animals = true,
|
||||||
specific_attack = { "player", "mobs_mc:sheep" },
|
specific_attack = {
|
||||||
|
"player",
|
||||||
|
"mobs_mc:sheep",
|
||||||
|
"mobs_mc:rabbit",
|
||||||
|
-- TODO: "mobs_mc:fox",
|
||||||
|
"mobs_mc:skeleton",
|
||||||
|
"mobs_mc:stray",
|
||||||
|
"mobs_mc:witherskeleton",
|
||||||
|
},
|
||||||
|
avoid_from = { "mobs_mc:llama" },
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mobs.register_mob("mobs_mc:wolf", wolf)
|
mcl_mobs.register_mob("mobs_mc:wolf", wolf)
|
||||||
|
|
|
@ -8,7 +8,7 @@ local is_sp = minetest.is_singleplayer()
|
||||||
local weather_mod = minetest.get_modpath("mcl_weather")
|
local weather_mod = minetest.get_modpath("mcl_weather")
|
||||||
local explosions_mod = minetest.get_modpath("mcl_explosions")
|
local explosions_mod = minetest.get_modpath("mcl_explosions")
|
||||||
local spawn_mod = minetest.get_modpath("mcl_spawn")
|
local spawn_mod = minetest.get_modpath("mcl_spawn")
|
||||||
local worlds_mod = minetest.get_modpath("mcl_worlds")
|
local pos_to_dim = minetest.get_modpath("mcl_worlds") and mcl_worlds.pos_to_dimension or function(pos) return "overworld" end
|
||||||
|
|
||||||
local function mcl_log (message)
|
local function mcl_log (message)
|
||||||
mcl_util.mcl_log (message, "[Beds]")
|
mcl_util.mcl_log (message, "[Beds]")
|
||||||
|
@ -38,6 +38,16 @@ local function is_night_skip_enabled()
|
||||||
return players_in_bed_setting() <= 100
|
return players_in_bed_setting() <= 100
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function players_in_overworld(players)
|
||||||
|
local count = 0
|
||||||
|
for n, player in ipairs(players) do
|
||||||
|
if player and pos_to_dim(player:get_pos()) == "overworld" then
|
||||||
|
count = count +1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
local function check_in_beds(players)
|
local function check_in_beds(players)
|
||||||
if not players then
|
if not players then
|
||||||
players = minetest.get_connected_players()
|
players = minetest.get_connected_players()
|
||||||
|
@ -45,7 +55,7 @@ local function check_in_beds(players)
|
||||||
if player_in_bed <= 0 then
|
if player_in_bed <= 0 then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return players_in_bed_setting() <= (player_in_bed * 100) / #players
|
return players_in_bed_setting() <= (player_in_bed * 100) / players_in_overworld(players)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- These monsters do not prevent sleep
|
-- These monsters do not prevent sleep
|
||||||
|
@ -206,10 +216,10 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function update_formspecs(finished, ges)
|
local function update_formspecs(finished, players)
|
||||||
local ges = ges or #minetest.get_connected_players()
|
local ges = players_in_overworld(players or minetest.get_connected_players())
|
||||||
local form_n = "size[12,5;true]"
|
local form_n = "size[12,5;true]"
|
||||||
local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges
|
local all_in_bed = ges and players_in_bed_setting() <= (player_in_bed * 100) / ges or 0
|
||||||
local night_skip = is_night_skip_enabled()
|
local night_skip = is_night_skip_enabled()
|
||||||
local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]"
|
local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]"
|
||||||
local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
|
local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
|
||||||
|
@ -349,13 +359,25 @@ function mcl_beds.get_bed_bottom (pos)
|
||||||
return bed_bottom
|
return bed_bottom
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function recheck_in_beds()
|
||||||
|
if check_in_beds() then
|
||||||
|
update_formspecs(is_night_skip_enabled())
|
||||||
|
mcl_beds.sleep()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check again (a player can change the dimension)
|
||||||
|
if player_in_bed > 0 then
|
||||||
|
update_formspecs(false)
|
||||||
|
minetest.after(5, recheck_in_beds)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function mcl_beds.on_rightclick(pos, player, is_top)
|
function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
-- Anti-Inception: Don't allow to sleep while you're sleeping
|
-- Anti-Inception: Don't allow to sleep while you're sleeping
|
||||||
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
|
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if worlds_mod then
|
local dim = pos_to_dim(pos)
|
||||||
local dim = mcl_worlds.pos_to_dimension(pos)
|
|
||||||
if dim == "nether" or dim == "end" then
|
if dim == "nether" or dim == "end" then
|
||||||
-- Bed goes BOOM in the Nether or End.
|
-- Bed goes BOOM in the Nether or End.
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
|
@ -368,7 +390,6 @@ function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local ppos = player:get_pos()
|
local ppos = player:get_pos()
|
||||||
|
|
||||||
|
@ -385,10 +406,13 @@ function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
mcl_title.set(player, "actionbar", {text=message, color="white", stay=60})
|
mcl_title.set(player, "actionbar", {text=message, color="white", stay=60})
|
||||||
else -- someone just successfully entered a bed
|
else -- someone just successfully entered a bed
|
||||||
local connected_players = minetest.get_connected_players()
|
local connected_players = minetest.get_connected_players()
|
||||||
local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, math.ceil(players_in_bed_setting() * #connected_players / 100))
|
local ges = players_in_overworld(connected_players)
|
||||||
|
local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, math.ceil(players_in_bed_setting() * ges / 100))
|
||||||
for _, player in pairs(connected_players) do
|
for _, player in pairs(connected_players) do
|
||||||
if not mcl_beds.player[player:get_player_name()] then -- only send message to players not sleeping.
|
-- only send message to players not sleeping and in the "overworld"
|
||||||
if mcl_title.params_get(player) then mcl_title.clear(player) end -- clear, old message is still being displayed
|
if not mcl_beds.player[player:get_player_name()] and pos_to_dim(player:get_pos()) == "overworld" then
|
||||||
|
-- clear, old message is still being displayed
|
||||||
|
if mcl_title.params_get(player) then mcl_title.clear(player) end
|
||||||
mcl_title.set(player, "actionbar", {text=sleep_hud_message, color="white", stay=60})
|
mcl_title.set(player, "actionbar", {text=sleep_hud_message, color="white", stay=60})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -401,12 +425,7 @@ function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
|
|
||||||
-- skip the night and let all players stand up
|
-- skip the night and let all players stand up
|
||||||
if check_in_beds() then
|
if check_in_beds() then
|
||||||
minetest.after(5, function()
|
minetest.after(5, recheck_in_beds)
|
||||||
if check_in_beds() then
|
|
||||||
update_formspecs(is_night_skip_enabled())
|
|
||||||
mcl_beds.sleep()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -434,14 +453,9 @@ minetest.register_on_leaveplayer(function(player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if check_in_beds(players) then
|
if check_in_beds(players) then
|
||||||
minetest.after(5, function()
|
minetest.after(5, recheck_in_beds)
|
||||||
if check_in_beds() then
|
|
||||||
update_formspecs(is_night_skip_enabled())
|
|
||||||
mcl_beds.sleep()
|
|
||||||
end
|
end
|
||||||
end)
|
update_formspecs(false, players)
|
||||||
end
|
|
||||||
update_formspecs(false, #players)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local message_rate_limit = tonumber(minetest.settings:get("chat_message_limit_per_10sec")) or 8 --NEVER change this! if this was java, i would've declared it as final
|
local message_rate_limit = tonumber(minetest.settings:get("chat_message_limit_per_10sec")) or 8 --NEVER change this! if this was java, i would've declared it as final
|
||||||
|
|
|
@ -191,6 +191,18 @@ minetest.register_craft({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "group:bee_nest",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "group:beehive",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
||||||
-- Temporary ABM to update honey levels
|
-- Temporary ABM to update honey levels
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "Update Beehive Honey Levels",
|
label = "Update Beehive Honey Levels",
|
||||||
|
|
|
@ -26,3 +26,9 @@ minetest.register_craft({
|
||||||
{ "group:wood", "group:wood", "" },
|
{ "group:wood", "group:wood", "" },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_cartography_table:cartography_table",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
|
@ -61,9 +61,9 @@ for _, row in ipairs(block.dyes) do
|
||||||
local sdesc_gtp = row[4]
|
local sdesc_gtp = row[4]
|
||||||
local sdesc_cp = row[5]
|
local sdesc_cp = row[5]
|
||||||
local sdesc_c = row[6]
|
local sdesc_c = row[6]
|
||||||
local ldesc_hc, ldesc_gt, ldesc_cp, ldesc_c
|
local ldesc_hc, ldesc_gt, ldesc_cp, ldesc_c, ldesc_gtp
|
||||||
local create_entry
|
local create_entry
|
||||||
local ename_hc, ename_gt, ename_cp, ename_c
|
local ename_hc, ename_gt, ename_cp, ename_c, ename_gtp
|
||||||
local ltt_cp = cp_tt
|
local ltt_cp = cp_tt
|
||||||
if is_canonical then
|
if is_canonical then
|
||||||
ldesc_hc = hc_desc
|
ldesc_hc = hc_desc
|
||||||
|
|
|
@ -164,6 +164,12 @@ minetest.register_node("mcl_core:deadbush", {
|
||||||
_mcl_hardness = 0,
|
_mcl_hardness = 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_core:deadbush",
|
||||||
|
burntime = 5,
|
||||||
|
})
|
||||||
|
|
||||||
minetest.register_node("mcl_core:barrier", {
|
minetest.register_node("mcl_core:barrier", {
|
||||||
description = S("Barrier"),
|
description = S("Barrier"),
|
||||||
_doc_items_longdesc = S("Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block."),
|
_doc_items_longdesc = S("Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block."),
|
||||||
|
|
|
@ -24,3 +24,9 @@ minetest.register_craft({
|
||||||
{ "group:wood", "group:wood", "" },
|
{ "group:wood", "group:wood", "" },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_fletching_table:fletching_table",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
|
@ -136,5 +136,11 @@ minetest.register_craft({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_lectern:lectern",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
||||||
-- Base Aliases.
|
-- Base Aliases.
|
||||||
minetest.register_alias("lectern", "mcl_lectern:lectern")
|
minetest.register_alias("lectern", "mcl_lectern:lectern")
|
||||||
|
|
|
@ -26,3 +26,9 @@ minetest.register_craft({
|
||||||
{ "group:wood", "group:wood", "" },
|
{ "group:wood", "group:wood", "" },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_loom:loom",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
|
@ -405,6 +405,12 @@ minetest.register_craft({
|
||||||
burntime = 15,
|
burntime = 15,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_mangrove:mangrove_roots",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
||||||
local adjacents = {
|
local adjacents = {
|
||||||
vector.new(1,0,0),
|
vector.new(1,0,0),
|
||||||
vector.new(-1,0,0),
|
vector.new(-1,0,0),
|
||||||
|
|
|
@ -257,6 +257,12 @@ minetest.register_craft({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "mcl_smithing_table:table",
|
||||||
|
burntime = 15,
|
||||||
|
})
|
||||||
|
|
||||||
-- this is the exact same as mcl_smithing_table.upgrade_item_netherite , in case something relies on the old function
|
-- this is the exact same as mcl_smithing_table.upgrade_item_netherite , in case something relies on the old function
|
||||||
function mcl_smithing_table.upgrade_item(itemstack)
|
function mcl_smithing_table.upgrade_item(itemstack)
|
||||||
return mcl_smithing_table.upgrade_item_netherite(itemstack)
|
return mcl_smithing_table.upgrade_item_netherite(itemstack)
|
||||||
|
|
Loading…
Reference in New Issue