Version 0.2

This commit is contained in:
BlockMen 2013-09-16 21:24:44 +02:00
parent b3f26b85cb
commit dbe9af6c61
13 changed files with 9057 additions and 30 deletions

View File

@ -1,15 +1,24 @@
Minetest mod "Pyramids" Minetest mod "Pyramids"
==================== =======================
version: 0.1 Beta version: 0.2 Beta
License of source code and textures: WTFPL License of source code and textures: WTFPL
----------------------------------------- ------------------------------------------
(c) Copyright BlockMen (2013) (c) Copyright BlockMen (2013)
Contributors: License of mesh model: WTFPL
------------- ----------------------------
cHyper (mine deep can be set by .conf) (c) Copyright Pavel_S (2013)
Licenses of sounds
------------------
The authors are : (freesound.org)
-mummy.1.ogg by Raventhornn, CC0
-mummy.2.ogg by Raventhornn, CC0
-mummy_hurt.1.ogg by Under7dude, CC0
-mummy_death.1.ogg by Michel88, CC-Sampling Plus 1.0
This program is free software. It comes without any warranty, to This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it the extent permitted by applicable law. You can redistribute it
@ -21,4 +30,5 @@ http://sam.zoy.org/wtfpl/COPYING for more details.
Using the mod: Using the mod:
-------------- --------------
This mod adds randomly spawned pyramids in deserts. The pyramids are very rare and contain a chest with stuff. This mod adds randomly spawned pyramids in deserts. The pyramids are very rare and contain a chest with stuff.
Also there are mummys inside, which attack the player if found in their radius.

View File

@ -1,3 +1,6 @@
dofile(minetest.get_modpath("pyramids").."/mummy.lua")
--dofile(minetest.get_modpath("pyramids").."/traps.lua")
local chest_stuff = { local chest_stuff = {
{name="default:apple", max = 3}, {name="default:apple", max = 3},
{name="farming:bread", max = 3}, {name="farming:bread", max = 3},
@ -11,6 +14,8 @@ local chest_stuff = {
local function fill_chest(pos) local function fill_chest(pos)
minetest.set_node(pos, {name="default:chest"}) minetest.set_node(pos, {name="default:chest"})
minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, {name="pyramids:spawner_mummy"})
if not minetest.setting_getbool("only_peaceful_mobs") then pyramids.spawn_mummy({x=pos.x+1,y=pos.y,z=pos.z},2) end
minetest.after(2, function() minetest.after(2, function()
local n = minetest.get_node(pos) local n = minetest.get_node(pos)
if n ~= nil then if n ~= nil then
@ -20,7 +25,7 @@ local function fill_chest(pos)
meta:set_string("infotext", "Chest") meta:set_string("infotext", "Chest")
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 8*4) inv:set_size("main", 8*4)
for i=0,2,1 do for i=0,4,1 do
local stuff = chest_stuff[math.random(1,#chest_stuff)] local stuff = chest_stuff[math.random(1,#chest_stuff)]
local stack = {name=stuff.name, count = math.random(1,stuff.max)} local stack = {name=stuff.name, count = math.random(1,stuff.max)}
if not inv:contains_item("main", stack) then if not inv:contains_item("main", stack) then
@ -33,49 +38,85 @@ local function fill_chest(pos)
end end
local function make_gang(pos) local function make_room(pos)
local loch = {x=pos.x+10,y=pos.y+7, z=pos.z+10} local loch = {x=pos.x+8,y=pos.y+5, z=pos.z+8}
for iy=0,6,1 do for iy=0,4,1 do
for ix=0,2,1 do for ix=0,6,1 do
for iz=0,2,1 do for iz=0,6,1 do
minetest.remove_node({x=loch.x+ix,y=loch.y-iy,z=loch.z+iz}) minetest.remove_node({x=loch.x+ix,y=loch.y-iy,z=loch.z+iz})
end end
end end
end end
fill_chest({x=pos.x+10+math.random(0,2),y=pos.y+1,z=pos.z+10+math.random(0,2)})
fill_chest({x=pos.x+10+math.random(0,2),y=pos.y+1,z=pos.z+10+math.random(0,2)})
end end
local function make_entrance(pos)
local gang = {x=pos.x+10,y=pos.y, z=pos.z}
for iy=2,3,1 do
for iz=0,7,1 do
--minetest.remove_node({x=gang.x,y=gang.y+iy,z=gang.z+iz})
minetest.remove_node({x=gang.x+1,y=gang.y+iy,z=gang.z+iz})
if iz >=3 and iy == 3 then
minetest.set_node({x=gang.x,y=gang.y+iy+1,z=gang.z+iz}, {name="default:sandstonebrick"})
minetest.set_node({x=gang.x+1,y=gang.y+iy+1,z=gang.z+iz}, {name="default:sandstonebrick"})
minetest.set_node({x=gang.x+2,y=gang.y+iy+1,z=gang.z+iz}, {name="default:sandstonebrick"})
end
end
end
end
local function make(pos) local function make(pos)
for iy=0,10,1 do--5,7 minetest.log("action", "Created pyramid at ("..pos.x..","..pos.y..","..pos.z..")")
for ix=iy,22-iy,1 do--12,16 for iy=0,10,1 do
for iz=iy,22-iy,1 do --12,16 for ix=iy,22-iy,1 do
minetest.set_node({x=pos.x+ix,y=pos.y+iy,z=pos.z+iz}, {name="default:sandstone"}) for iz=iy,22-iy,1 do
minetest.set_node({x=pos.x+ix,y=pos.y+iy,z=pos.z+iz}, {name="default:sandstonebrick"})
end end
end end
end end
make_gang(pos) make_room(pos)
make_entrance(pos)
end end
local perl1 = {
SEED1 = 9130, -- Values should match minetest mapgen V6 desert noise.
OCTA1 = 3,
PERS1 = 0.5,
SCAL1 = 250,
}
local function ground(pos)
local p2 = pos
while minetest.get_node(p2).name == "air" do
p2.y = p2.y -1
end
return p2
end
minetest.register_on_generated(function(minp, maxp, seed) minetest.register_on_generated(function(minp, maxp, seed)
local perlin1 = minetest.env:get_perlin(perl1.SEED1, perl1.OCTA1, perl1.PERS1, perl1.SCAL1)
local mpos = {x=math.random(minp.x,maxp.x), y=math.random(minp.y,maxp.y), z=math.random(minp.z,maxp.z)} local mpos = {x=math.random(minp.x,maxp.x), y=math.random(minp.y,maxp.y), z=math.random(minp.z,maxp.z)}
if mpos.y <= 0 then return end local noise1 = perlin1:get2d({x=mpos.x,y=mpos.y})
if minetest.get_node(mpos) and minetest.get_node(mpos).name == "default:desert_sand" then
make(mpos)
end
mpos = {x=math.random(minp.x,maxp.x), y=math.random(minp.y,maxp.y), z=math.random(minp.z,maxp.z)} if noise1 > 0.45 or math.random(0,10) > (0.45 - noise1) * 100 then -- Smooth transition 0.35 to 0.45
if mpos.y <= 0 then return end p2 = minetest.find_node_near(mpos, 25, {"default:desert_sand"})
if minetest.get_node(mpos) and minetest.get_node(mpos).name == "default:desert_sand" then
mpos.y = mpos.y-3 if p2 == nil then return end
make(mpos) if p2.y < 0 then return end
if math.random(0,18) < 17 then return end
local off = 0
opos = {x=p2.x+22,y=p2.y-1,z=p2.z+22}
if minetest.get_node(opos).name == "air" then
p2 = ground(opos)
end
p2.y = p2.y - 4
if p2.y < 0 then p2.y = 0 end
minetest.after(0.3,make,p2)
end end
end) end)

BIN
models/pyramids_hit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

BIN
models/pyramids_mummy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

8573
models/pyramids_mummy.x Normal file

File diff suppressed because it is too large Load Diff

403
mummy.lua Normal file
View File

@ -0,0 +1,403 @@
pyramids = {}
walk_limit = 1
chillaxin_speed = 1
animation_speed = 10
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
animation_blend = 0
-- Default player appearance
mummy_mesh = "pyramids_mummy.x"
mummy_texture = {"pyramids_mummy.png"}
mummy_hp = 20
mummy_drop = "default:papyrus"
local sound_normal = "mummy"
local sound_hit = "mummy_hurt"
local sound_dead = "mummy_death"
local spawner_range = 17
local spawner_max_mobs = 6
function get_animations_def()
return {
stand_START = 74,
stand_END = 74,
sit_START = 81,
sit_END = 160,
lay_START = 162,
lay_END = 166,
walk_START = 74,
walk_END = 105,
mine_START = 74,
mine_END = 105,
walk_mine_START = 74,
walk_mine_END = 105
}
end
local npc_model = {}
local npc_anim = {}
local npc_sneak = {}
local ANIM_STAND = 1
local ANIM_SIT = 2
local ANIM_LAY = 3
local ANIM_WALK = 4
local ANIM_WALK_MINE = 5
local ANIM_MINE = 6
function hit(self)
prop = {
mesh = mummy_mesh,
textures = {"pyramids_mummy.png^pyramids_hit.png"},
}
self.object:set_properties(prop)
minetest.after(0.4, function()
prop = {textures = mummy_texture,}
self.object:set_properties(prop)
end)
end
function npc_update_visuals_def(self)
--local name = get_player_name()
visual = default_model_def
npc_anim = 0 -- Animation will be set further below immediately
--npc_sneak[name] = false
prop = {
mesh = mummy_mesh,
textures = mummy_texture,
--visual_size = {x=1, y=1, z=1},
}
self.object:set_properties(prop)
end
NPC_ENTITY_DEF = {
physical = true,
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4},
visual = "mesh",
visual_size = {x=8,y=8},
mesh = mummy_mesh,
textures = mummy_texture,
makes_footstep_sound = true,
npc_anim = 0,
timer = 0,
turn_timer = 0,
vec = 0,
yaw = 0,
yawwer = 0,
state = 1,
jump_timer = 0,
punch_timer = 0,
sound_timer = 0,
attacker = "",
attacking_timer = 0,
mob_name = "mummy"
}
spawner_DEF = {
hp_max = 1,
physical = true,
collisionbox = {0,0,0,0,0,0},
visual = "mesh",
visual_size = {x=3.3,y=3.3},
mesh = mummy_mesh,
textures = mummy_texture,
makes_footstep_sound = false,
timer = 0,
automatic_rotate = math.pi * 2.9,
m_name = "dummy"
}
spawner_DEF.on_activate = function(self)
npc_update_visuals_def(self)
self.object:setvelocity({x=0, y=0, z=0})
self.object:setacceleration({x=0, y=0, z=0})
self.object:set_armor_groups({immortal=1})
end
spawner_DEF.on_step = function(self, dtime)
self.timer = self.timer + 0.01
end
spawner_DEF.on_punch = function(self, hitter)
end
NPC_ENTITY_DEF.on_activate = function(self)
npc_update_visuals_def(self)
self.anim = get_animations_def()
self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed, animation_blend)
self.npc_anim = ANIM_STAND
self.object:setacceleration({x=0,y=-20,z=0})--20
self.state = 1
self.object:set_hp(mummy_hp)
self.object:set_armor_groups({fleshy=130})
end
NPC_ENTITY_DEF.on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
--attack as group
--[[for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 5)) do
if not object:is_player() then
if object:get_luaentity().name == "peaceful_npc:npc_def" then
object:get_luaentity().state = 3
object:get_luaentity().attacker = puncher:get_player_name()
end
end
end]]
--if self.state ~= 3 then
--self.state = 3
self.attacker = puncher--:get_player_name()
--end
if puncher ~= nil then
local sound = sound_hit
if self.object:get_hp() == 0 then sound = sound_dead end
minetest.sound_play(sound, {to_player = puncher:get_player_name(), loop = false, gain = 0.3})
if time_from_last_punch >= 0.45 then
hit(self)
--local dir = puncher:get_look_dir()
--self.direction = dir
self.direction = {x=self.object:getvelocity().x, y=self.object:getvelocity().y, z=self.object:getvelocity().z}
self.punch_timer = 0
self.object:setvelocity({x=dir.x*chillaxin_speed,y=5,z=dir.z*chillaxin_speed})--self.object:setvelocity({x=dir.x*4,y=5,z=dir.z*4})
if self.state == 1 then
self.state = 8
elseif self.state >= 2 then
self.state = 9
end
end
end
if self.object:get_hp() == 0 then
local obj = minetest.env:add_item(self.object:getpos(), mummy_drop.." "..math.random(0,3))
end
end
local cnt1 = 0
local cnt2 = 0
NPC_ENTITY_DEF.on_step = function(self, dtime)
self.timer = self.timer + 0.01
self.turn_timer = self.turn_timer + 0.01
self.jump_timer = self.jump_timer + 0.01
self.punch_timer = self.punch_timer + 0.01
self.attacking_timer = self.attacking_timer + 0.01
self.sound_timer = self.sound_timer + 0.01
local current_pos = self.object:getpos()
local current_node = minetest.env:get_node(current_pos)
if self.time_passed == nil then
self.time_passed = 0
end
--self.time_passed = self.time_passed + dtime
if self.object:get_hp() == 0 then-- self.object:remove() end
--if self.time_passed >= 5 then
minetest.sound_play(sound_dead, {pos = current_pos, max_hear_distance = 10 , gain = 0.3})
self.object:remove()
end--else
if current_node.name == "default:water_source" or current_node.name == "default:water_flowing" or current_node.name == "default:lava_source" or current_node.name == "default:lava_flowing" then
--self.time_passed = self.time_passed + dtime
self.sound_timer = self.sound_timer + dtime
if self.sound_timer >= 0.8 then
self.sound_timer = 0
self.object:set_hp(self.object:get_hp()-5)
hit(self)
minetest.sound_play(sound_hit, {pos = current_pos, max_hear_distance = 10, gain = 0.3})
end
else
self.time_passed = 0
end
--end
--update moving state every 1 or 2 seconds
if self.state < 3 then
if self.timer > math.random(1,2) then
if self.attacker == "" then
self.state = math.random(1,2)
else self.state = 1 end
self.timer = 0
end
end
--play sound
if self.sound_timer > math.random(5,35) then
minetest.sound_play(sound_normal, {pos = current_pos, max_hear_distance = 10, gain = 0.2})
self.sound_timer = 0
end
--after punched
if self.state >= 8 then
if self.punch_timer > 0.15 then
--self.direction = {x = math.sin(self.yaw)*-1, y = -20, z = math.cos(self.yaw)}
if self.state == 9 then
self.object:setvelocity({x=self.direction.x*chillaxin_speed,y=-20,z=self.direction.z*chillaxin_speed})
self.state = 2
elseif self.state == 8 then
self.object:setvelocity({x=0,y=-20,z=0})
self.state = 1
end
end
end
--STANDING
if self.state == 1 then
self.yawwer = true
self.attacker = ""
for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 4)) do
if object:is_player() then
self.yawwer = false
NPC = self.object:getpos()
PLAYER = object:getpos()
self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z}
self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
if PLAYER.x > NPC.x then
self.yaw = self.yaw + math.pi
end
self.yaw = self.yaw - 2
self.object:setyaw(self.yaw)
self.attacker = object--:get_player_name()
end
end
if self.attacker == "" and self.turn_timer > math.random(1,4) then--and yawwer == true then
self.yaw = 360 * math.random()
self.object:setyaw(self.yaw)
self.turn_timer = 0
self.direction = {x = math.sin(self.yaw)*-1, y = -20, z = math.cos(self.yaw)}
end
self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0})
if self.npc_anim ~= ANIM_STAND then
self.anim = get_animations_def()
self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed, animation_blend)
self.npc_anim = ANIM_STAND
end
if self.attacker ~= "" then
self.direction = {x = math.sin(self.yaw)*-1, y = -20, z = math.cos(self.yaw)}
self.state = 2
end
end
--WALKING
if self.state == 2 then
if self.direction ~= nil then
self.object:setvelocity({x=self.direction.x*chillaxin_speed,y=self.object:getvelocity().y,z=self.direction.z*chillaxin_speed})
end
if self.turn_timer > math.random(1,4) and not self.attacker then
self.yaw = 360 * math.random()
self.object:setyaw(self.yaw)
self.turn_timer = 0
self.direction = {x = math.sin(self.yaw)*-1, y = -20, z = math.cos(self.yaw)}
--self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=direction.z})
--self.object:setacceleration(self.direction)
end
if self.npc_anim ~= ANIM_WALK then
self.anim = get_animations_def()
self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed, animation_blend)
self.npc_anim = ANIM_WALK
end
--[[jump
if self.direction ~= nil then
if self.jump_timer > 0.3 then
if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then
self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z})
self.jump_timer = 0
end
end
end]]
if self.attacker ~= "" and minetest.setting_getbool("enable_damage") then
local s = self.object:getpos()
local p = self.attacker:getpos()
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
if dist < 2 and self.attacking_timer > 0.6 then
self.attacker:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups = {fleshy=1}
})
self.attacking_timer = 0
end
end
end
end
minetest.register_entity("pyramids:mummy", NPC_ENTITY_DEF)
minetest.register_entity("pyramids:mummy_spawner", spawner_DEF)
--spawn-egg/spawner
minetest.register_craftitem("pyramids:spawn_egg", {
description = "Mummy spawn-egg",
inventory_image = "pyramids_mummy_egg.png",
liquids_pointable = false,
stack_max = 99,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
minetest.env:add_entity(pointed_thing.above,"pyramids:mummy")
if not minetest.setting_getbool("creative_mode") then itemstack:take_item() end
return itemstack
end
end,
})
function pyramids.spawn_mummy (pos, number)
for i=0,number do
minetest.env:add_entity(pos,"pyramids:mummy")
end
end
minetest.register_node("pyramids:spawner_mummy", {
description = "Mummy spawner",
paramtype = "light",
tiles = {"pyramids_spawner.png"},
is_ground_content = true,
drawtype = "allfaces",--_optional",
groups = {cracky=1,level=1},
drop = "",
on_construct = function(pos)
pos.y = pos.y - 0.28
minetest.env:add_entity(pos,"pyramids:mummy_spawner")
end,
on_destruct = function(pos)
for _,obj in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do
if not obj:is_player() then
if obj ~= nil and obj:get_luaentity().m_name == "dummy" then
obj:remove()
end
end
end
end
})
if not minetest.setting_getbool("only_peaceful_mobs") then
minetest.register_abm({
nodenames = {"pyramids:spawner_mummy"},
interval = 2.0,
chance = 20,
action = function(pos, node, active_object_count, active_object_count_wider)
local player_near = false
local mobs = 0
for _,obj in ipairs(minetest.env:get_objects_inside_radius(pos, spawner_range)) do
if obj:is_player() then
player_near = true
else
if obj:get_luaentity().mob_name == "mummy" then mobs = mobs + 1 end
end
end
if player_near then
if mobs < spawner_max_mobs then
pos.x = pos.x+1
local p = minetest.find_node_near(pos, 5, {"air"})
minetest.env:add_entity(p,"pyramids:mummy")
end
end
end
})
end

BIN
sounds/mummy.1.ogg Normal file

Binary file not shown.

BIN
sounds/mummy.2.ogg Normal file

Binary file not shown.

BIN
sounds/mummy_death.1.ogg Normal file

Binary file not shown.

BIN
sounds/mummy_hurt.1.ogg Normal file

Binary file not shown.

BIN
textures/pyramids_crack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B