mobf_core/mobf/weapons.lua
sapier 14f8a7d6bf Animals Modpack 1.9.10
-fixed group support for mobs
-fixed sun damage handler resetting animation to "stand"
-fix orientation not updated correct for mobs following new default state schema
-fixed bug 2d sprites not shown correctly
-fixed doku
-added support for upright sprites
-added 3d mesh model for dm
-added 3d mesh models for chicken
-added sounds for some mod
-added license information
-added support for mobf without fire mod
-added non inventory_plus settings gui (requres core patch)
-replaced custom debug chatcommand handlers by official minetest ones
2013-01-04 23:49:58 +00:00

328 lines
9.0 KiB
Lua

-------------------------------------------------------------------------------
-- Mob Framework Mod by Sapier
--
-- You may copy, use, modify or do nearly anything except removing this
-- copyright notice.
-- And of course you are NOT allow to pretend you have written it.
--
--! @file weapons.lua
--! @brief weapon related functions
--! @copyright Sapier
--! @author Sapier
--! @date 2012-08-09
--
--! @defgroup weapons Weapons
--! @brief weapon entitys predefined by mob framework (can be extended by mod)
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
local weapons_spacer = {} --unused to fix lua doxygen bug only
-------------------------------------------------------------------------------
-- name: mobf_init_weapons = function(self, dtime)
--
--! @brief initialize weapons handled by mobf mod
--
-------------------------------------------------------------------------------
function mobf_init_weapons()
minetest.register_entity(":mobf:fireball_entity", MOBF_FIREBALL_ENTITY)
minetest.register_entity(":mobf:plasmaball_entity", MOBF_PLASMABALL_ENTITY)
end
-------------------------------------------------------------------------------
-- name: mobf_do_area_damage(pos,immune,damage,range)
--
--! @brief damage all objects within a certain range
--
--! @param pos cennter of damage area
--! @param immune object immune to damage
--! @param damage damage to be done
--! @param range range around pos
-------------------------------------------------------------------------------
function mobf_do_area_damage(pos,immune,damage,range)
--damage objects within inner blast radius
objs = minetest.env:get_objects_inside_radius(pos, range)
for k, obj in pairs(objs) do
--don't do damage to issuer
if obj ~= immune then
obj:set_hp(obj:get_hp()-damage)
end
end
end
-------------------------------------------------------------------------------
-- name: mobf_do_node_damage(pos,immune_list,range,chance)
--
--! @brief damage all nodes within a certain range
--
--! @param pos center of area
--! @param immune_list list of nodes immune to damage
--! @param range range to do damage
--! @param chance chance damage is done to a node
-------------------------------------------------------------------------------
function mobf_do_node_damage(pos,immune_list,range,chance)
--do node damage
for i=pos.x-range, pos.x+range, 1 do
for j=pos.y-range, pos.y+range, 1 do
for k=pos.z-range,pos.z+range,1 do
--TODO create a little bit more sophisticated blast resistance
if math.random() < chance then
local toremove = minetest.env:get_node({x=i,y=j,z=k})
if toremove ~= nil then
local immune = false
if immune_list ~= nil then
for i,v in ipairs(immune_list) do
if (torremove.name == v) then
immune = true
end
end
end
if immune ~= true then
minetest.env:remove_node({x=i,y=j,z=k})
end
end
end
end
end
end
end
--! @class MOBF_FIREBALL_ENTITY
--! @ingroup weapons
--! @brief a fireball weapon entity
MOBF_FIREBALL_ENTITY = {
physical = false,
textures = {"animals_fireball.png"},
collisionbox = {0,0,0,0,0,0},
damage_range = 4,
velocity = 3,
gravity = -0.01,
damage = 15,
owner = 0,
lifetime = 30,
created = -1,
}
-------------------------------------------------------------------------------
-- name: MOBF_FIREBALL_ENTITY.on_activate = function(self, staticdata)
--
--! @brief onactivate callback for fireball
--! @memberof MOBF_FIREBALL_ENTITY
--! @private
--
--! @param self fireball itself
--! @param staticdata
-------------------------------------------------------------------------------
function MOBF_FIREBALL_ENTITY.on_activate(self,staticdata)
self.created = mobf_get_current_time()
end
-------------------------------------------------------------------------------
-- name: MOBF_FIREBALL_ENTITY.surfacefire = function(self, staticdata)
--
--! @brief place fire on surfaces around pos
--! @memberof MOBF_FIREBALL_ENTITY
--! @private
--
--! @param pos position to place fire around
--! @param range square around pos to set on fire
-------------------------------------------------------------------------------
function MOBF_FIREBALL_ENTITY.surfacefire(pos,range)
if mobf_rtd.fire_enabled then
--start fire on any surface within inner damage range
for i=pos.x-range/2, pos.x+range/2, 1 do
for j=pos.y-range/2, pos.y+range/2, 1 do
for k=pos.z-range/2, pos.z+range/2, 1 do
local current = minetest.env:get_node({x=i,y=j,z=k})
local ontop = minetest.env:get_node({x=i,y=j+1,z=k})
--print("put fire? " .. printpos({x=i,y=j,z=k}) .. " " .. current.name .. " " ..ontop.name)
if (current.name ~= "air") and
(current.name ~= "fire:basic_flame") and
(ontop.name == "air") then
minetest.env:set_node({x=i,y=j+1,z=k}, {name="fire:basic_flame"})
end
end
end
end
else
minetest.log(LOGLEVEL_ERROR,"MOBF: A fireball without fire mod??!? You're kidding!!")
end
end
-------------------------------------------------------------------------------
-- name: MOBF_FIREBALL_ENTITY.on_step = function(self, dtime)
--
--! @brief onstep callback for fireball
--! @memberof MOBF_FIREBALL_ENTITY
--! @private
--
--! @param self fireball itself
--! @param dtime time since last callback
-------------------------------------------------------------------------------
function MOBF_FIREBALL_ENTITY.on_step(self, dtime)
local pos = self.object:getpos()
local node = minetest.env:get_node(pos)
--detect hit
local objs=minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1)
local hit = false
for k, obj in pairs(objs) do
if obj:get_entity_name() ~= "mobf:fireball_entity" and
obj ~= self.owner then
hit=true
end
end
if hit then
--damage objects within inner blast radius
mobf_do_area_damage(pos,self.owner,self.damage_range/4,self.damage/4)
--damage all objects within blast radius
mobf_do_area_damage(pos,self.owner,self.damage_range/2,self.damage/2)
MOBF_FIREBALL_ENTITY.surfacefire(pos,self.damage_range)
self.object:remove()
end
-- vanish when hitting a node
if node.name ~= "air" then
MOBF_FIREBALL_ENTITY.surfacefire(pos,self.damage_range)
self.object:remove()
end
--remove after lifetime has passed
if self.created > 0 and
self.created + self.lifetime < mobf_get_current_time() then
self.object:remove()
end
end
--! @class MOBF_PLASMABALL_ENTITY
--! @ingroup weapons
--! @brief a plasmaball weapon entity
MOBF_PLASMABALL_ENTITY = {
physical = false,
textures = {"animals_plasmaball.png"},
lastpos={},
collisionbox = {0,0,0,0,0,0},
damage_range = 2,
velocity = 4,
gravity = -0.001,
damage = 8,
owner = 0,
lifetime = 30,
created = -1,
}
-------------------------------------------------------------------------------
-- name: MOBF_PLASMABALL_ENTITY.on_activate = function(self, staticdata)
--
--! @brief onactivate callback for plasmaball
--! @memberof MOBF_PLASMABALL_ENTITY
--! @private
--
--! @param self fireball itself
--! @param staticdata
-------------------------------------------------------------------------------
function MOBF_PLASMABALL_ENTITY.on_activate(self,staticdata)
self.created = mobf_get_current_time()
end
-------------------------------------------------------------------------------
-- name: MOBF_PLASMABALL_ENTITY.on_step = function(self, dtime)
--
--! @brief onstep callback for plasmaball
--! @memberof MOBF_PLASMABALL_ENTITY
--! @private
--
--! @param self plasmaball itself
--! @param dtime time since last callback
-------------------------------------------------------------------------------
function MOBF_PLASMABALL_ENTITY.on_step(self, dtime)
local pos = self.object:getpos()
local node = minetest.env:get_node(pos)
--detect hit
local objs=minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1)
local hit = false
for k, obj in pairs(objs) do
if obj:get_entity_name() ~= "mobf:plasmaball_entity" and
obj ~= self.owner then
hit=true
end
end
--damage all objects not hit but at least passed
mobf_do_area_damage(pos,self.owner,2,1)
if hit then
--damage objects within inner blast radius
mobf_do_area_damage(pos,self.owner,self.damage_range/4,self.damage/2)
--damage all objects within blast radius
mobf_do_area_damage(pos,self.owner,self.damage_range/2,self.damage/2)
end
-- vanish when hitting a node
if node.name ~= "air" or
hit then
--replace this loop by minetest.env:find_node_near?
--do node damage
for i=pos.x-1, pos.x+1, 1 do
for j=pos.y-1, pos.y+1, 1 do
for k=pos.z-1,pos.z+1,1 do
--TODO create a little bit more sophisticated blast resistance
if math.random() < 0.5 then
local toremove = minetest.env:get_node({x=i,y=j,z=k})
if toremove ~= nil and
toremove.name ~= "default:stone" and
toremove.name ~= "default:cobble" then
minetest.env:remove_node({x=i,y=j,z=k})
end
end
end
end
end
self.object:remove()
end
--remove after lifetime has passed
if self.created > 0 and
self.created + self.lifetime < mobf_get_current_time() then
self.object:remove()
end
end