Merge pull request 'Release 0.71.14 Spawn Ender Dragon' (#106) from testing into production

Reviewed-on: MineClone5/MineClone5#106
This commit is contained in:
kay27 2022-01-05 02:52:58 +00:00
commit 980e592e4a
5 changed files with 78 additions and 27 deletions

View File

@ -214,6 +214,7 @@ end
--a function used for despawning mobs --a function used for despawning mobs
mobs.check_for_player_within_area = function(self, radius) mobs.check_for_player_within_area = function(self, radius)
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
if not pos1 then return end
--get players in radius --get players in radius
for _,player in pairs(minetest_get_connected_players()) do for _,player in pairs(minetest_get_connected_players()) do
if player and player:get_hp() > 0 then if player and player:get_hp() > 0 then

View File

@ -73,7 +73,7 @@ local ARROW_ENTITY={
_stuckin=nil, --Position of node in which arow is stuck. _stuckin=nil, --Position of node in which arow is stuck.
_shooter=nil, -- ObjectRef of player or mob who shot it _shooter=nil, -- ObjectRef of player or mob who shot it
_is_arrow = true, _is_arrow = true,
_in_player = false,
_viscosity=0, -- Viscosity of node the arrow is currently in _viscosity=0, -- Viscosity of node the arrow is currently in
_deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession _deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession
} }
@ -439,6 +439,7 @@ function ARROW_ENTITY.get_staticdata(self)
is_critical = self._is_critical, is_critical = self._is_critical,
stuck = self._stuck, stuck = self._stuck,
stuckin = self._stuckin, stuckin = self._stuckin,
stuckin_player = self._in_player,
} }
if self._stuck then if self._stuck then
-- If _stucktimer is missing for some reason, assume the maximum -- If _stucktimer is missing for some reason, assume the maximum
@ -453,21 +454,10 @@ function ARROW_ENTITY.get_staticdata(self)
return minetest.serialize(out) return minetest.serialize(out)
end end
local function remove_arrow_on_joinplayer(staticdata, self)
if not staticdata.activated then
staticdata.activated = true
else
self.object:remove()
end
end
function ARROW_ENTITY.on_activate(self, staticdata, dtime_s) function ARROW_ENTITY.on_activate(self, staticdata, dtime_s)
self._time_in_air = 1.0 self._time_in_air = 1.0
self._in_player = false
local data = minetest.deserialize(staticdata) local data = minetest.deserialize(staticdata)
if data then if data then
remove_arrow_on_joinplayer(data, self)
self._stuck = data.stuck self._stuck = data.stuck
if data.stuck then if data.stuck then
if data.stuckstarttime then if data.stuckstarttime then
@ -498,10 +488,23 @@ function ARROW_ENTITY.on_activate(self, staticdata, dtime_s)
self._shooter = shooter self._shooter = shooter
end end
end end
if data.stuckin_player then
self.object:remove()
end
end end
self.object:set_armor_groups({ immortal = 1 }) self.object:set_armor_groups({ immortal = 1 })
end end
minetest.register_on_respawnplayer(function(player)
for _, obj in pairs(player:get_children()) do
local ent = obj:get_luaentity()
if ent and ent.name and string.find(ent.name, "mcl_bows:arrow_entity") then
obj:remove()
end
end
end)
minetest.register_entity("mcl_bows:arrow_entity", ARROW_ENTITY) minetest.register_entity("mcl_bows:arrow_entity", ARROW_ENTITY)
if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then

View File

@ -1,5 +1,5 @@
name = mcl_enchanting name = mcl_enchanting
description = Enchanting for MineClone2 description = Enchanting for MineClone2
depends = tt, walkover, mcl_sounds, mcl_colors depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience
optional_depends = screwdriver optional_depends = screwdriver
author = Fleckenstein author = Fleckenstein

View File

@ -1247,16 +1247,43 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_
return lvm_used return lvm_used
end end
local function generate_end_exit_portal(pos) local dragon_spawn_pos = false
local obj = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") local dragon_spawned, portal_generated = false, false
if obj then
local function spawn_ender_dragon()
local obj = minetest.add_entity(dragon_spawn_pos, "mobs_mc:enderdragon")
if not obj then return false end
local dragon_entity = obj:get_luaentity() local dragon_entity = obj:get_luaentity()
dragon_entity._initial = true dragon_entity._initial = true
dragon_entity._portal_pos = pos dragon_entity._portal_pos = pos
else return obj
minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn")
end end
mcl_structures.call_struct(pos, "end_exit_portal")
local function try_to_spawn_ender_dragon()
if spawn_ender_dragon() then
dragon_spawned = true
return
end
minetest.after(2, try_to_spawn_ender_dragon)
minetest.log("warning", "[mcl_mapgen_core] WARNING! Ender dragon doesn't want to spawn at "..minetest.pos_to_string(dragon_spawn_pos))
end
if portal_generated and not dragon_spawned then
minetest.after(10, try_to_spawn_ender_dragon)
end
local function generate_end_exit_portal(pos)
if dragon_spawn_pos then return false end
dragon_spawn_pos = vector.add(pos, vector.new(3, 11, 3))
mcl_structures.call_struct(pos, "end_exit_portal", nil, nil, function()
minetest.after(2, function()
minetest.emerge_area(vector.subtract(dragon_spawn_pos, {x = 64, y = 12, z = 5}), vector.add(dragon_spawn_pos, {x = 3, y = 3, z = 5}), function(blockpos, action, calls_remaining, param)
if calls_remaining > 0 then return end
minetest.after(2, try_to_spawn_ender_dragon)
end)
end)
end)
portal_generated = true
end end
-- TODO: Try to use more efficient structure generating code -- TODO: Try to use more efficient structure generating code

View File

@ -69,7 +69,7 @@ local function init_node_construct(pos)
end end
-- The call of Struct -- The call of Struct
function mcl_structures.call_struct(pos, struct_style, rotation, pr) function mcl_structures.call_struct(pos, struct_style, rotation, pr, callback)
minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos)) minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos))
if not rotation then if not rotation then
rotation = "random" rotation = "random"
@ -91,13 +91,31 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr)
elseif struct_style == "fossil" then elseif struct_style == "fossil" then
return mcl_structures.generate_fossil(pos, rotation, pr) return mcl_structures.generate_fossil(pos, rotation, pr)
elseif struct_style == "end_exit_portal" then elseif struct_style == "end_exit_portal" then
return mcl_structures.generate_end_exit_portal(pos, rotation) return mcl_structures.generate_end_exit_portal(pos, rotation, pr, callback)
elseif struct_style == "end_exit_portal_open" then elseif struct_style == "end_exit_portal_open" then
return mcl_structures.generate_end_exit_portal_open(pos, rotation) return mcl_structures.generate_end_exit_portal_open(pos, rotation)
elseif struct_style == "end_gateway_portal" then elseif struct_style == "end_gateway_portal" then
return mcl_structures.generate_end_gateway_portal(pos, rotation) return mcl_structures.generate_end_gateway_portal(pos, rotation)
elseif struct_style == "end_portal_shrine" then elseif struct_style == "end_portal_shrine" then
return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) return mcl_structures.generate_end_portal_shrine(pos, rotation, pr)
elseif struct_style == "end_portal" then
return mcl_structures.generate_end_portal(pos, rotation, pr)
end
end
function mcl_structures.generate_end_portal(pos, rotation, pr)
-- todo: proper facedir
local x0, y0, z0 = pos.x - 2, pos.y, pos.z - 2
for x = 0, 4 do
for z = 0, 4 do
if x % 4 == 0 or z % 4 == 0 then
if x % 4 ~= 0 or z % 4 ~= 0 then
minetest.swap_node({x = x0 + x, y = y0, z = z0 + z}, {name = "mcl_portals:end_portal_frame_eye"})
end
else
minetest.swap_node({x = x0 + x, y = y0, z = z0 + z}, {name = "mcl_portals:portal_end"})
end
end
end end
end end
@ -324,9 +342,9 @@ function mcl_structures.generate_fossil(pos, rotation, pr)
return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true) return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true)
end end
function mcl_structures.generate_end_exit_portal(pos, rot) function mcl_structures.generate_end_exit_portal(pos, rot, pr, callback)
local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts" local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts"
return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true) return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true, nil, callback)
end end
function mcl_structures.generate_end_exit_portal_open(pos, rot) function mcl_structures.generate_end_exit_portal_open(pos, rot)
@ -556,7 +574,7 @@ end
-- Debug command -- Debug command
minetest.register_chatcommand("spawnstruct", { minetest.register_chatcommand("spawnstruct", {
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon", params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | end_portal | nether_portal | dungeon",
description = S("Generate a pre-defined structure near your position."), description = S("Generate a pre-defined structure near your position."),
privs = {debug = true}, privs = {debug = true},
func = function(name, param) func = function(name, param)
@ -596,6 +614,8 @@ minetest.register_chatcommand("spawnstruct", {
mcl_structures.generate_end_portal_shrine(pos, rot, pr) mcl_structures.generate_end_portal_shrine(pos, rot, pr)
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
mcl_dungeons.spawn_dungeon(pos, rot, pr) mcl_dungeons.spawn_dungeon(pos, rot, pr)
elseif param == "end_portal" then
mcl_structures.generate_end_portal(pos, rot, pr)
elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then
mcl_portals.spawn_nether_portal(pos, rot, pr, name) mcl_portals.spawn_nether_portal(pos, rot, pr, name)
elseif param == "" then elseif param == "" then