wands and wand focuses
This commit is contained in:
parent
a8bcab584f
commit
65f7492d52
262
focuses.lua
262
focuses.lua
@ -1,5 +1,12 @@
|
|||||||
-- Wand Focuses
|
-- Wand Focuses
|
||||||
|
|
||||||
|
-- Constants
|
||||||
|
-- TODO: make settings
|
||||||
|
magicalities.magic_spray_count = 16
|
||||||
|
magicalities.elemental_focus_velocity = 16
|
||||||
|
magicalities.elemental_focus_consumption = 5
|
||||||
|
|
||||||
|
-- Teleportation
|
||||||
minetest.register_craftitem("magicalities:focus_teleport", {
|
minetest.register_craftitem("magicalities:focus_teleport", {
|
||||||
description = "Wand Focus of Teleportation",
|
description = "Wand Focus of Teleportation",
|
||||||
groups = {wand_focus = 1},
|
groups = {wand_focus = 1},
|
||||||
@ -40,6 +47,7 @@ minetest.register_craftitem("magicalities:focus_teleport", {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Node swapper
|
||||||
minetest.register_craftitem("magicalities:focus_swap", {
|
minetest.register_craftitem("magicalities:focus_swap", {
|
||||||
description = "Wand Focus of Swapping",
|
description = "Wand Focus of Swapping",
|
||||||
groups = {wand_focus = 1},
|
groups = {wand_focus = 1},
|
||||||
@ -74,7 +82,7 @@ minetest.register_craftitem("magicalities:focus_swap", {
|
|||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
local drops = minetest.get_node_drops(pos)
|
local drops = minetest.get_node_drops(node.name)
|
||||||
|
|
||||||
if ndef.can_dig ~= nil and not ndef.can_dig(pos, user) then
|
if ndef.can_dig ~= nil and not ndef.can_dig(pos, user) then
|
||||||
return itemstack
|
return itemstack
|
||||||
@ -114,12 +122,15 @@ minetest.register_craftitem("magicalities:focus_swap", {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
---------------
|
||||||
|
-- Tunneling --
|
||||||
|
---------------
|
||||||
|
|
||||||
local tunneler_memory = {}
|
local tunneler_memory = {}
|
||||||
local tunneler_depth = 8
|
local tunneler_depth = 8
|
||||||
|
|
||||||
local function reset_tunnel(tid)
|
local function reset_tunnel(tid)
|
||||||
local infos = tunneler_memory['t' .. tid]
|
local infos = tunneler_memory[tid]
|
||||||
if not infos then return end
|
if not infos then return end
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
local manip = minetest.get_voxel_manip()
|
||||||
@ -138,15 +149,13 @@ local function reset_tunnel(tid)
|
|||||||
manip:write_to_map()
|
manip:write_to_map()
|
||||||
|
|
||||||
tunneler_memory['t' .. tid] = nil
|
tunneler_memory['t' .. tid] = nil
|
||||||
|
|
||||||
t = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function create_tunnel(pos, dir, owner)
|
local function create_tunnel(pos, dir, owner)
|
||||||
-- Ensure no double tunnels
|
-- Ensure no double tunnels
|
||||||
for id,data in pairs(tunneler_memory) do
|
for id,data in pairs(tunneler_memory) do
|
||||||
if data.owner == owner then
|
if data.owner == owner then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -207,7 +216,7 @@ local function create_tunnel(pos, dir, owner)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if abort then return end
|
if abort then return false end
|
||||||
|
|
||||||
-- Set nodes in map
|
-- Set nodes in map
|
||||||
manip:set_data(data)
|
manip:set_data(data)
|
||||||
@ -226,7 +235,8 @@ local function create_tunnel(pos, dir, owner)
|
|||||||
owner = owner,
|
owner = owner,
|
||||||
}
|
}
|
||||||
|
|
||||||
minetest.after(10, reset_tunnel, cnum)
|
minetest.after(10, reset_tunnel, 't' .. cnum)
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_node("magicalities:tunnel_node", {
|
minetest.register_node("magicalities:tunnel_node", {
|
||||||
@ -246,7 +256,9 @@ minetest.register_craftitem("magicalities:focus_tunnel", {
|
|||||||
inventory_image = "magicalities_focus_tunnel.png",
|
inventory_image = "magicalities_focus_tunnel.png",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
_wand_requirements = {
|
_wand_requirements = {
|
||||||
["air"] = 1
|
["dark"] = 10,
|
||||||
|
["light"] = 10,
|
||||||
|
["earth"] = 10,
|
||||||
},
|
},
|
||||||
_wand_use = function (itemstack, user, pointed_thing)
|
_wand_use = function (itemstack, user, pointed_thing)
|
||||||
if not pointed_thing.above or pointed_thing.type ~= "node" then return itemstack end
|
if not pointed_thing.above or pointed_thing.type ~= "node" then return itemstack end
|
||||||
@ -256,6 +268,12 @@ minetest.register_craftitem("magicalities:focus_tunnel", {
|
|||||||
dir = minetest.wallmounted_to_dir(wm)
|
dir = minetest.wallmounted_to_dir(wm)
|
||||||
|
|
||||||
minetest.after(0.1, create_tunnel, pointed_thing.above, dir, user:get_player_name())
|
minetest.after(0.1, create_tunnel, pointed_thing.above, dir, user:get_player_name())
|
||||||
|
itemstack = magicalities.wands.wand_take_contents(itemstack, {
|
||||||
|
["dark"] = 10,
|
||||||
|
["light"] = 10,
|
||||||
|
["earth"] = 10,
|
||||||
|
})
|
||||||
|
magicalities.wands.update_wand_desc(itemstack)
|
||||||
|
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
@ -266,3 +284,231 @@ minetest.register_on_shutdown(function ()
|
|||||||
reset_tunnel(id)
|
reset_tunnel(id)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
-- Elemental Attacks --
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
local special_fn = {}
|
||||||
|
|
||||||
|
-- Particles
|
||||||
|
local randparticles = PcgRandom(os.clock())
|
||||||
|
local function shoot_particles (user, velocity, color)
|
||||||
|
if not color then
|
||||||
|
color = ""
|
||||||
|
else
|
||||||
|
color = "^[multiply:"..color
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Calculate velocity
|
||||||
|
local dir = user:get_look_dir()
|
||||||
|
local vel = {x=0,y=0,z=0}
|
||||||
|
vel.x = dir.x * velocity
|
||||||
|
vel.y = dir.y * velocity
|
||||||
|
vel.z = dir.z * velocity
|
||||||
|
|
||||||
|
-- Calculate position
|
||||||
|
local pos = user:get_pos()
|
||||||
|
pos.x = pos.x + (dir.x * 2)
|
||||||
|
pos.y = pos.y + (dir.y * 2) + 1.5
|
||||||
|
pos.z = pos.z + (dir.z * 2)
|
||||||
|
|
||||||
|
for i = 1, magicalities.magic_spray_count do
|
||||||
|
-- Deviation
|
||||||
|
local relvel = {x=0,y=0,z=0}
|
||||||
|
relvel.x = vel.x + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
relvel.y = vel.y + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
relvel.z = vel.z + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
minetest.add_particle({
|
||||||
|
pos = pos,
|
||||||
|
velocity = relvel,
|
||||||
|
acceleration = relvel,
|
||||||
|
expirationtime = 1,
|
||||||
|
size = 4,
|
||||||
|
collisiondetection = true,
|
||||||
|
collision_removal = true,
|
||||||
|
texture = "magicalities_spark.png"..color,
|
||||||
|
-- animation = {Tile Animation definition},
|
||||||
|
glow = 2
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function shoot_spray(user, dmg, vel, color, hit_fn)
|
||||||
|
shoot_particles(user, vel, color)
|
||||||
|
|
||||||
|
minetest.after(0.05, function()
|
||||||
|
local pos = user:get_pos()
|
||||||
|
local dir = user:get_look_dir()
|
||||||
|
|
||||||
|
local x = math.random(-1,1)*0.1
|
||||||
|
local y = math.random(-1,1)*0.1
|
||||||
|
local z = math.random(-1,1)*0.1
|
||||||
|
local scatternum = math.random(2, magicalities.magic_spray_count / 2)
|
||||||
|
|
||||||
|
for i = 1, scatternum do
|
||||||
|
local relvel = {x=0,y=0,z=0}
|
||||||
|
relvel.x = dir.x * vel + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
relvel.y = dir.y * vel + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
relvel.z = dir.z * vel + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
||||||
|
|
||||||
|
local dmglow = dmg - math.floor(dmg / scatternum)
|
||||||
|
local reldmg = math.random(dmglow, dmg)
|
||||||
|
|
||||||
|
local e=minetest.add_entity({x=pos.x+x,y=pos.y+1.5+y,z=pos.z+z}, "magicalities:magic_spray")
|
||||||
|
e:set_velocity(relvel)
|
||||||
|
e:set_yaw(user:get_look_yaw()+math.pi)
|
||||||
|
e:get_luaentity():set_dmg(reldmg)
|
||||||
|
e:get_luaentity():set_user(user)
|
||||||
|
if hit_fn then
|
||||||
|
e:get_luaentity():set_hit_function(hit_fn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Attack
|
||||||
|
local on_hit_object = function(self, target, hp, user)
|
||||||
|
target:punch(user, 1, {full_punch_interval = 1, damage_groups = {fleshy = hp, magic = hp * 2}}, nil)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local magic_remove = function(self)
|
||||||
|
if self.object:get_attach() then self.object:set_detach() end
|
||||||
|
if self.target then self.target:punch(self.object, 1,{full_punch_interval=1,damage_groups={fleshy=4}}, nil) end
|
||||||
|
self.object:set_hp(0)
|
||||||
|
self.object:punch(self.object, 1,{full_punch_interval=1.0,damage_groups={fleshy=4}}, nil)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local magic_spray = {
|
||||||
|
initial_properties = {
|
||||||
|
hp_max = 1,
|
||||||
|
physical = false,
|
||||||
|
collide_with_objects = false,
|
||||||
|
collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3},
|
||||||
|
visual = "sprite",
|
||||||
|
visual_size = {x = 0.4, y = 0.4},
|
||||||
|
textures = {"[combine:16x16"},
|
||||||
|
pointable = false,
|
||||||
|
},
|
||||||
|
struck = false,
|
||||||
|
timer = 0,
|
||||||
|
hit_fn = nil,
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
self.timer = self.timer + 1
|
||||||
|
if self.timer > 80 or self.struck then
|
||||||
|
magic_remove(self)
|
||||||
|
end
|
||||||
|
local pos=self.object:get_pos()
|
||||||
|
local no=minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
|
if no.walkable and not self.struck then
|
||||||
|
if self.hit_fn and special_fn[self.hit_fn] and special_fn[self.hit_fn].on_hit_node then
|
||||||
|
special_fn[self.hit_fn].on_hit_node(self, pos, minetest.get_node(pos), self.user)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.struck = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
for i, ob in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||||
|
if (ob and not self.struck) and ((ob:is_player() and ob:get_player_name() ~= self.user:get_player_name()) or (ob:get_luaentity() and ob:get_luaentity().physical and ob:get_luaentity().name~="__builtin:item" )) then
|
||||||
|
self.object:set_velocity({x=0, y=0, z=0})
|
||||||
|
on_hit_object(self, ob, self.dmg / 2, self.user)
|
||||||
|
if self.hit_fn and special_fn[self.hit_fn] and special_fn[self.hit_fn].on_hit_object then
|
||||||
|
special_fn[self.hit_fn].on_hit_object(self, ob, self.dmg / 2, self.user)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.struck = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end,
|
||||||
|
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||||
|
if not self.target then return self end
|
||||||
|
if not self.hp then self.hp = self.object:get_hp() end
|
||||||
|
local hp = self.object:get_hp()
|
||||||
|
local hurt = self.hp-self.object:get_hp()
|
||||||
|
self.hp = self.object:get_hp()
|
||||||
|
self.target:set_hp(self.target:get_hp() - hurt)
|
||||||
|
self.target:punch(self.object, hurt, {full_punch_interval = 1.0, damage_groups = {fleshy=4}}, "default:sword_wood", nil)
|
||||||
|
if hurt > 100 or hp <= hurt then
|
||||||
|
self.target:set_detach()
|
||||||
|
self.target:set_velocity({x=0, y=4, z=0})
|
||||||
|
self.on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) end
|
||||||
|
magic_remove(self)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
function magic_spray:set_dmg(dmg)
|
||||||
|
self.dmg = dmg
|
||||||
|
end
|
||||||
|
|
||||||
|
function magic_spray:set_user(user)
|
||||||
|
self.user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
function magic_spray:set_hit_function(hit_fn)
|
||||||
|
self.hit_fn = hit_fn
|
||||||
|
end
|
||||||
|
|
||||||
|
function magicalities.register_elemental_focus (element, description, damage, hit_fn)
|
||||||
|
local el = magicalities.elements[element]
|
||||||
|
minetest.register_craftitem("magicalities:focus_atk_"..element, {
|
||||||
|
description = "Wand Focus of "..el.description.."\n"..description,
|
||||||
|
groups = {wand_focus = 1},
|
||||||
|
inventory_image = "magicalities_focus_atk_"..element..".png",
|
||||||
|
stack_max = 1,
|
||||||
|
_wand_requirements = {
|
||||||
|
[element] = magicalities.elemental_focus_consumption
|
||||||
|
},
|
||||||
|
_wand_use = function (itemstack, user, pointed_thing)
|
||||||
|
if not user or user:get_player_name() == "" then return itemstack end
|
||||||
|
|
||||||
|
itemstack = magicalities.wands.wand_take_contents(itemstack, {[element] = magicalities.elemental_focus_consumption})
|
||||||
|
magicalities.wands.update_wand_desc(itemstack)
|
||||||
|
shoot_spray(user, damage, magicalities.elemental_focus_velocity, el.color, hit_fn)
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function magicalities.register_focus_atk_special(name, fns)
|
||||||
|
special_fn[name] = fns
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register everything
|
||||||
|
|
||||||
|
minetest.register_entity("magicalities:magic_spray", magic_spray)
|
||||||
|
|
||||||
|
magicalities.register_elemental_focus("air", "Deals some damage to enemies", 2)
|
||||||
|
magicalities.register_elemental_focus("earth", "Deals some damage to enemies", 4)
|
||||||
|
magicalities.register_elemental_focus("water", "Spawns water sources", 3, "setwater")
|
||||||
|
magicalities.register_elemental_focus("fire", "Lights things on fire", 8, "setfire")
|
||||||
|
|
||||||
|
magicalities.register_focus_atk_special("setfire", {
|
||||||
|
on_hit_node = function (self, pos, node, user)
|
||||||
|
local toppos = vector.add(pos, {x=0,y=1,z=0})
|
||||||
|
local topnode = minetest.get_node_or_nil(toppos)
|
||||||
|
if not topnode or topnode.name ~= "air" then return end
|
||||||
|
if minetest.is_protected(toppos, user:get_player_name()) then return end
|
||||||
|
minetest.set_node(toppos, {name="fire:basic_flame"})
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
local function set_water(self, _, __, user)
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
local toppos = vector.add(pos, {x=0,y=1,z=0})
|
||||||
|
local topnode = minetest.get_node_or_nil(toppos)
|
||||||
|
if not topnode or topnode.name ~= "air" then return end
|
||||||
|
if minetest.is_protected(toppos, user:get_player_name()) then return end
|
||||||
|
minetest.set_node(toppos, {name="default:water_source"})
|
||||||
|
end
|
||||||
|
|
||||||
|
magicalities.register_focus_atk_special("setwater", {
|
||||||
|
on_hit_object = set_water,
|
||||||
|
on_hit_node = set_water,
|
||||||
|
})
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 1.2 KiB |
BIN
textures/magicalities_focus_atk_air.png
Normal file
BIN
textures/magicalities_focus_atk_air.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
textures/magicalities_focus_atk_earth.png
Normal file
BIN
textures/magicalities_focus_atk_earth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
textures/magicalities_focus_atk_fire.png
Normal file
BIN
textures/magicalities_focus_atk_fire.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/magicalities_focus_atk_water.png
Normal file
BIN
textures/magicalities_focus_atk_water.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
37
wands.lua
37
wands.lua
@ -13,8 +13,6 @@ local wandcaps = {
|
|||||||
damage_groups = {fleshy = 2},
|
damage_groups = {fleshy = 2},
|
||||||
}
|
}
|
||||||
|
|
||||||
local randparticles = PcgRandom(os.clock())
|
|
||||||
|
|
||||||
local function align(len)
|
local function align(len)
|
||||||
local str = ""
|
local str = ""
|
||||||
for i = 1, len do
|
for i = 1, len do
|
||||||
@ -48,9 +46,11 @@ local function focuses_formspec(available, focusname)
|
|||||||
local x = 0
|
local x = 0
|
||||||
local fsp = ""
|
local fsp = ""
|
||||||
for focus in pairs(available) do
|
for focus in pairs(available) do
|
||||||
|
if x < 5 then
|
||||||
fsp = fsp .. "item_image_button["..x..",2.8;1,1;"..focus..";"..focus..";]"
|
fsp = fsp .. "item_image_button["..x..",2.8;1,1;"..focus..";"..focus..";]"
|
||||||
x = x + 1
|
x = x + 1
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local current = ""
|
local current = ""
|
||||||
if not focusname then
|
if not focusname then
|
||||||
@ -281,39 +281,6 @@ local function use_wand(itemstack, user, pointed_thing)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Calculate velocity
|
|
||||||
local dir = user:get_look_dir()
|
|
||||||
local vel = {x=0,y=0,z=0}
|
|
||||||
vel.x = dir.x * 16
|
|
||||||
vel.y = dir.y * 16
|
|
||||||
vel.z = dir.z * 16
|
|
||||||
|
|
||||||
-- Calculate position
|
|
||||||
local pos = user:get_pos()
|
|
||||||
pos.x = pos.x + (dir.x * 2)
|
|
||||||
pos.y = pos.y + (dir.y * 2) + 1.5
|
|
||||||
pos.z = pos.z + (dir.z * 2)
|
|
||||||
|
|
||||||
for i = 1, 16 do
|
|
||||||
-- Deviation
|
|
||||||
local relvel = {x=0,y=0,z=0}
|
|
||||||
relvel.x = vel.x + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
|
||||||
relvel.y = vel.y + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
|
||||||
relvel.z = vel.z + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000)
|
|
||||||
minetest.add_particle({
|
|
||||||
pos = pos,
|
|
||||||
velocity = relvel,
|
|
||||||
acceleration = relvel,
|
|
||||||
expirationtime = 1,
|
|
||||||
size = 4,
|
|
||||||
collisiondetection = true,
|
|
||||||
collision_removal = true,
|
|
||||||
texture = "magicalities_spark.png",
|
|
||||||
-- animation = {Tile Animation definition},
|
|
||||||
glow = 2
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
magicalities.wands.update_wand_desc(itemstack)
|
magicalities.wands.update_wand_desc(itemstack)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user