Add dungeon master

pull/4/head
PilzAdam 2012-09-21 15:37:53 +02:00
parent 86664b5cbb
commit 3fc06c2392
8 changed files with 169 additions and 2 deletions

View File

@ -59,7 +59,11 @@ This mod add some functions that you can use in other mods:
lava_damage: the damage per second if the mob is in lava lava_damage: the damage per second if the mob is in lava
light_damage: the damage per second if the mob is in light light_damage: the damage per second if the mob is in light
on_rightclick: its same as in minetest.register_entity() on_rightclick: its same as in minetest.register_entity()
3. mobs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per_30_block_radius) attack_type: the attack type of a monster ("dogfight", "shoot",
maybe somehting like "explode" in the future (creeper))
arrow: if the attack_type="shoot" needed: the entity name of the arrow
shoot_interval: the minimum shoot interval
2. mobs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per_30_block_radius)
This function adds the spawning of an animal (without it the This function adds the spawning of an animal (without it the
registered animals and monster won't spawn!) registered animals and monster won't spawn!)
"name" is the name of the animal/monster "name" is the name of the animal/monster
@ -69,6 +73,17 @@ This mod add some functions that you can use in other mods:
"chance" is same as in register_abm() "chance" is same as in register_abm()
"mobs_per_30_block_radius" is the maximum number of mobs in a 30 block "mobs_per_30_block_radius" is the maximum number of mobs in a 30 block
radius arround the possible spawning pos radius arround the possible spawning pos
3. mobs:register_arrow(name, def)
"name" is the name of the arrow
"def" is a table with the following values:
visual: same is in minetest.register_entity()
visual_size: same is in minetest.register_entity()
textures: same is in minetest.register_entity()
velocity: the velocity of the arrow
hit_player: a function that is called when the arrow hits a player
params: (self, player)
hit_node: a function that is called when the arrow hits a node
params: (self, pos, node)
License: License:
Sourcecode: WTFPL (see below) Sourcecode: WTFPL (see below)

71
api.lua
View File

@ -20,6 +20,9 @@ function mobs:register_mob(name, def)
drawtype = def.drawtype, drawtype = def.drawtype,
on_rightclick = def.on_rightclick, on_rightclick = def.on_rightclick,
type = def.type, type = def.type,
attack_type = def.attack_type,
arrow = def.arrow,
shoot_interval = def.shoot_interval,
timer = 0, timer = 0,
attack = {player=nil, dist=nil}, attack = {player=nil, dist=nil},
@ -160,7 +163,7 @@ function mobs:register_mob(name, def)
v.y = 5 v.y = 5
self.object:setvelocity(v) self.object:setvelocity(v)
end end
elseif self.state == "attack" then elseif self.state == "attack" and self.attack_type == "dogfight" then
local s = self.object:getpos() local s = self.object:getpos()
local p = self.attack.player:getpos() local p = self.attack.player:getpos()
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
@ -220,6 +223,43 @@ function mobs:register_mob(name, def)
}, vec) }, vec)
end end
end end
elseif self.state == "attack" and self.attack_type == "shoot" then
local s = self.object:getpos()
local p = self.attack.player:getpos()
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
if dist > self.view_range or self.attack.player:get_hp() <= 0 then
self.state = "stand"
self.v_start = false
self.set_velocity(self, 0)
self.attack = {player=nil, dist=nil}
return
else
self.attack.dist = dist
end
local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
local yaw = math.atan(vec.z/vec.x)+math.pi/2
if self.drawtype == "side" then
yaw = yaw+(math.pi/2)
end
if p.x > s.x then
yaw = yaw+math.pi
end
self.object:setyaw(yaw)
self.set_velocity(self, 0)
if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then
self.timer = 0
local obj = minetest.env:add_entity(self.object:getpos(), self.arrow)
local amount = (vec.x^2+vec.y^2+vec.z^2)^0.5
local v = obj:get_luaentity().velocity
vec.y = vec.y+1
vec.x = vec.x*v/amount
vec.y = vec.y*v/amount
vec.z = vec.z*v/amount
obj:setvelocity(vec)
end
end end
end, end,
@ -310,3 +350,32 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per
end end
}) })
end end
function mobs:register_arrow(name, def)
minetest.register_entity(name, {
physical = false,
visual = def.visual,
visual_size = def.visual_size,
textures = def.textures,
velocity = def.velocity,
hit_player = def.hit_player,
hit_node = def.hit_node,
on_step = function(self, dtime)
local pos = self.object:getpos()
if minetest.env:get_node(self.object:getpos()).name ~= "air" then
self.hit_node(self, pos, node)
self.object:remove()
return
end
pos.y = pos.y-1
for _,player in pairs(minetest.env:get_objects_inside_radius(pos, 1)) do
if player:is_player() then
self.hit_player(self, player)
self.object:remove()
return
end
end
end
})
end

View File

@ -1 +1,2 @@
default default
fire

View File

@ -24,6 +24,7 @@ mobs:register_mob("mobs:dirt_monster", {
lava_damage = 5, lava_damage = 5,
light_damage = 2, light_damage = 2,
on_rightclick = nil, on_rightclick = nil,
attack_type = "dogfight",
}) })
mobs:register_spawn("mobs:dirt_monster", {"default:dirt_with_grass"}, 3, -1, 5000, 5) mobs:register_spawn("mobs:dirt_monster", {"default:dirt_with_grass"}, 3, -1, 5000, 5)
@ -51,6 +52,7 @@ mobs:register_mob("mobs:stone_monster", {
water_damage = 0, water_damage = 0,
lava_damage = 0, lava_damage = 0,
light_damage = 0, light_damage = 0,
attack_type = "dogfight",
}) })
mobs:register_spawn("mobs:stone_monster", {"default:stone"}, 3, -1, 5000, 5) mobs:register_spawn("mobs:stone_monster", {"default:stone"}, 3, -1, 5000, 5)
@ -79,6 +81,7 @@ mobs:register_mob("mobs:sand_monster", {
water_damage = 3, water_damage = 3,
lava_damage = 1, lava_damage = 1,
light_damage = 0, light_damage = 0,
attack_type = "dogfight",
}) })
mobs:register_spawn("mobs:sand_monster", {"default:desert_sand"}, 20, -1, 5000, 5) mobs:register_spawn("mobs:sand_monster", {"default:desert_sand"}, 20, -1, 5000, 5)
@ -207,5 +210,84 @@ mobs:register_mob("mobs:oerkki", {
water_damage = 1, water_damage = 1,
lava_damage = 1, lava_damage = 1,
light_damage = 0, light_damage = 0,
attack_type = "dogfight",
}) })
mobs:register_spawn("mobs:oerkki", {"default:stone"}, 2, -1, 5000, 5) mobs:register_spawn("mobs:oerkki", {"default:stone"}, 2, -1, 5000, 5)
mobs:register_mob("mobs:dungeon_master", {
type = "monster",
hp_max = 10,
collisionbox = {-0.8, -1.21875, -0.8, 0.8, 1.21875, 0.8},
visual = "upright_sprite",
visual_size = {x=1.875, y=2.4375},
textures = {"mobs_dungeon_master.png", "mobs_dungeon_master_back.png"},
makes_footstep_sound = true,
view_range = 15,
walk_velocity = 1,
run_velocity = 3,
damage = 4,
drops = {
{name = "default:mese",
chance = 100,
min = 1,
max = 2,},
},
armor = 2,
drawtype = "front",
water_damage = 1,
lava_damage = 1,
light_damage = 0,
on_rightclick = nil,
attack_type = "shoot",
arrow = "mobs:fireball",
shoot_interval = 2.5,
})
mobs:register_spawn("mobs:dungeon_master", {"default:stone"}, 2, -1, 5000, 0)
mobs:register_arrow("mobs:fireball", {
visual = "sprite",
visual_size = {x=1, y=1},
--textures = {{name="mobs_fireball.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.5}}}, FIXME
textures = {"mobs_fireball.png"},
velocity = 5,
hit_player = function(self, player)
local s = self.object:getpos()
local p = player:getpos()
local vec = {x=s.x-p.x, y=s.y-p.y, z=s.z-p.z}
player:punch(self.object, 1.0, {
full_punch_interval=1.0,
groupcaps={
fleshy={times={[1]=1/2, [2]=1/3, [3]=1/4}},
}
}, vec)
local pos = self.object:getpos()
for dx=-1,1 do
for dy=-1,1 do
for dz=-1,1 do
local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
local n = minetest.env:get_node(pos).name
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30 then
minetest.env:set_node(p, {name="fire:basic_flame"})
else
minetest.env:remove_node(p)
end
end
end
end
end,
hit_node = function(self, pos, node)
for dx=-1,1 do
for dy=-2,1 do
for dz=-1,1 do
local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
local n = minetest.env:get_node(pos).name
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30 then
minetest.env:set_node(p, {name="fire:basic_flame"})
else
minetest.env:remove_node(p)
end
end
end
end
end
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

BIN
textures/mobs_fireball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B