Implement fire spell, add license.
|
@ -0,0 +1,31 @@
|
|||
Licenses for any modifications made for this modpack and the following mods in this modpack: kingdoms, magic
|
||||
Other mods will contain appropriate README or LICENSE files.
|
||||
|
||||
License for Code
|
||||
----------------
|
||||
|
||||
Copyright (c) 2016-2017 Beha
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
License for Textures, Models and Sounds
|
||||
---------------------------------------
|
||||
|
||||
CC BY-SA 4.0. Created by Beha.
|
|
@ -68,7 +68,20 @@ minetest.register_craftitem("kingdoms:silver_lump", {
|
|||
minetest.register_craftitem("kingdoms:silver_ingot", {
|
||||
description = "Silver Ingot",
|
||||
inventory_image = "kingdoms_silver_ingot.png",
|
||||
groups = {spellbinding = 1},
|
||||
groups = {spellbinding = 1, minor_spellbinding = 1},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("kingdoms:silver_shard", {
|
||||
description = "Silver Shard",
|
||||
inventory_image = "kingdoms_silver_shard.png",
|
||||
groups = {minor_spellbinding = 1},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'kingdoms:silver_shard 9',
|
||||
recipe = {
|
||||
{'kingdoms:silver_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -87,6 +100,15 @@ minetest.register_craft({
|
|||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'kingdoms:silver_ingot',
|
||||
recipe = {
|
||||
{'kingdoms:silver_shard', 'kingdoms:silver_shard', 'kingdoms:silver_shard'},
|
||||
{'kingdoms:silver_shard', 'kingdoms:silver_shard', 'kingdoms:silver_shard'},
|
||||
{'kingdoms:silver_shard', 'kingdoms:silver_shard', 'kingdoms:silver_shard'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "kingdoms:silver_ingot",
|
||||
|
|
After Width: | Height: | Size: 419 B |
|
@ -92,7 +92,7 @@ minetest.register_craftitem("magic:null_essence", {
|
|||
inventory_image = "magic_essence.png",
|
||||
})
|
||||
|
||||
function magic.register_crystal(def, craft)
|
||||
function magic.register_crystal(def, nocraft)
|
||||
minetest.register_node("magic:crystal_"..def.name, {
|
||||
description = def.desc.." Crystal",
|
||||
drawtype = "glasslike",
|
||||
|
@ -164,11 +164,11 @@ function magic.register_crystal(def, craft)
|
|||
end
|
||||
end
|
||||
|
||||
if craft then
|
||||
if not nocraft then
|
||||
magic.register_crystal_craft(def)
|
||||
end
|
||||
end
|
||||
|
||||
for _,def in ipairs(magic.crystals) do
|
||||
magic.register_crystal(def, true)
|
||||
magic.register_crystal(def)
|
||||
end
|
||||
|
|
|
@ -24,6 +24,7 @@ minetest.override_item("default:mese", {
|
|||
|
||||
domodfile("crafts.lua")
|
||||
domodfile("crystals.lua")
|
||||
domodfile("throwing.lua")
|
||||
domodfile("spells.lua")
|
||||
domodfile("timegens.lua")
|
||||
domodfile("mapgen.lua")
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
function magic.register_spell(name, def)
|
||||
local item_def = {
|
||||
description = def.description,
|
||||
inventory_image = "magic_essence.png^[colorize:"..def.color..":"..tostring(0xCC).."^magic_emblem_"..def.emblem..".png",
|
||||
groups = def.groups or {spell = 1},
|
||||
}
|
||||
if def.type == "missile" then
|
||||
magic.register_missile(name.."_missile", item_def.inventory_image, def)
|
||||
item_def.on_use = function(itemstack, player, pointed_thing)
|
||||
local playerpos = player:getpos()
|
||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.4,z=playerpos.z}, name.."_missile")
|
||||
local dir = player:get_look_dir()
|
||||
obj:setvelocity({x=dir.x*def.speed, y=dir.y*def.speed, z=dir.z*def.speed})
|
||||
obj:setacceleration({x=dir.x*-3, y=-8.5*def.gravity, z=dir.z*-3})
|
||||
obj:setyaw(player:get_look_yaw()+math.pi)
|
||||
if obj:get_luaentity() then
|
||||
obj:get_luaentity().player = player
|
||||
else
|
||||
obj:remove()
|
||||
end
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
end
|
||||
else
|
||||
error("Unknown spell type: "..def.type)
|
||||
end
|
||||
minetest.register_craftitem(name, item_def)
|
||||
end
|
||||
magic.register_spell("magic:spell_fire", {
|
||||
description = "Fire Spell",
|
||||
type = "missile",
|
||||
color = "#F00",
|
||||
emblem = "attack",
|
||||
speed = 30,
|
||||
gravity = 0,
|
||||
hit_node = function(self, pos, last_empty_pos)
|
||||
local flammable = minetest.get_item_group(minetest.get_node(pos).name, "flammable")
|
||||
if flammable > 0 then
|
||||
minetest.set_node(pos, {name = "fire:basic_flame"})
|
||||
return true
|
||||
elseif last_empty_pos then
|
||||
minetest.set_node(last_empty_pos, {name = "fire:basic_flame"})
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "magic:spell_fire",
|
||||
recipe = {
|
||||
{"magic:rage_essence", "group:minor_spellbinding"},
|
||||
},
|
||||
})
|
After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,231 @@
|
|||
-- Throwing movement physics.
|
||||
|
||||
local safe_ents = {
|
||||
["__builtin:item"] = true,
|
||||
["itemframes:item"] = true,
|
||||
["xdecor:f_item"] = true,
|
||||
}
|
||||
|
||||
local TIMEOUT = 300
|
||||
|
||||
-- COPIED FROM technic, under LGPL v2
|
||||
-- BEGIN COPIED
|
||||
local scalar = vector.scalar or vector.dot or function(v1, v2)
|
||||
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
|
||||
end
|
||||
|
||||
local function biggest_of_vec(vec)
|
||||
if vec.x < vec.y then
|
||||
if vec.y < vec.z then
|
||||
return "z"
|
||||
end
|
||||
return "y"
|
||||
end
|
||||
if vec.x < vec.z then
|
||||
return "z"
|
||||
end
|
||||
return "x"
|
||||
end
|
||||
|
||||
local function rayIter(pos, dir, range)
|
||||
-- make a table of possible movements
|
||||
local step = {}
|
||||
for i in pairs(pos) do
|
||||
local v = math.sign(dir[i])
|
||||
if v ~= 0 then
|
||||
step[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
local p
|
||||
return function()
|
||||
if not p then
|
||||
-- avoid skipping the first position
|
||||
p = vector.round(pos)
|
||||
return vector.new(p)
|
||||
end
|
||||
|
||||
-- find the position which has the smallest distance to the line
|
||||
local choose = {}
|
||||
local choosefit = vector.new()
|
||||
for i in pairs(step) do
|
||||
choose[i] = vector.new(p)
|
||||
choose[i][i] = choose[i][i] + step[i]
|
||||
choosefit[i] = scalar(vector.normalize(vector.subtract(choose[i], pos)), dir)
|
||||
end
|
||||
p = choose[biggest_of_vec(choosefit)]
|
||||
|
||||
if vector.distance(pos, p) <= range then
|
||||
return vector.new(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- END COPIED
|
||||
|
||||
function magic.register_missile(name, texture, def)
|
||||
|
||||
def.hit_object = def.hit_object or function(self, pos, obj)
|
||||
return true
|
||||
end
|
||||
|
||||
def.hit_player = def.hit_player or function(self, pos, obj)
|
||||
return true
|
||||
end
|
||||
|
||||
def.hit_node = def.hit_node or function(self, pos, last_empty_pos)
|
||||
return true
|
||||
end
|
||||
|
||||
def.is_passthrough_node = def.is_passthrough_node or function(self, pos, node)
|
||||
return node.name == "air"
|
||||
end
|
||||
|
||||
local ent_def = {
|
||||
physical = false,
|
||||
timer=0,
|
||||
visual = "sprite",
|
||||
visual_size = {x=0.4, y=0.4},
|
||||
textures = {texture},
|
||||
lastpos={},
|
||||
lastair = nil,
|
||||
collisionbox = {0,0,0,0,0,0},
|
||||
}
|
||||
|
||||
ent_def.on_step = function(self, dtime)
|
||||
self.timer=self.timer+dtime
|
||||
local pos = self.object:getpos()
|
||||
if self.lastpos.x == nil then
|
||||
self.lastpos = pos
|
||||
if def.is_passthrough_node(self, pos, minetest.get_node(pos).name) then
|
||||
self.lastair = pos
|
||||
elseif def.is_passthrough_node(self, vector.add(pos, {x=0, y=1, z=0}), minetest.get_node(vector.add(pos, {x=0, y=1, z=0}))) then
|
||||
self.lastair = vector.add(pos, {x=0, y=1, z=0})
|
||||
elseif def.is_passthrough_node(self, vector.add(pos, {x=0, y=2, z=0}), minetest.get_node(vector.add(pos, {x=0, y=2, z=0}))) then
|
||||
self.lastair = vector.add(pos, {x=0, y=2, z=0})
|
||||
end
|
||||
end
|
||||
|
||||
if self.timer > TIMEOUT then
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
local line = {
|
||||
start = self.lastpos,
|
||||
finish = pos,
|
||||
middle = {
|
||||
x = (self.lastpos.x + pos.x) / 2,
|
||||
y = (self.lastpos.y + pos.y) / 2,
|
||||
z = (self.lastpos.z + pos.z) / 2,
|
||||
},
|
||||
}
|
||||
|
||||
local Hit = {x=0, y=0, z=0};
|
||||
|
||||
local function GetIntersection(fDst1, fDst2, P1, P2)
|
||||
if ( (fDst1 * fDst2) >= 0.0) then return nil end
|
||||
if ( fDst1 == fDst2) then return nil end
|
||||
Hit = vector.multiply(vector.add(P1, vector.subtract(P2, P1)), ( -fDst1/(fDst2-fDst1) ));
|
||||
return true
|
||||
end
|
||||
|
||||
local function InBox(H, B1, B2, Axis)
|
||||
if ( Axis==1 and H.z > B1.z and H.z < B2.z and H.y > B1.y and H.y < B2.y) then return true; end
|
||||
if ( Axis==2 and H.z > B1.z and H.z < B2.z and H.x > B1.x and H.x < B2.x) then return true; end
|
||||
if ( Axis==3 and H.x > B1.x and H.x < B2.x and H.y > B1.y and H.y < B2.y) then return true; end
|
||||
return false;
|
||||
end
|
||||
|
||||
local function CheckLineBox( B1, B2, L1, L2)
|
||||
if (L2.x < B1.x and L1.x < B1.x) then return false end
|
||||
if (L2.x > B2.x and L1.x > B2.x) then return false end
|
||||
if (L2.y < B1.y and L1.y < B1.y) then return false end
|
||||
if (L2.y > B2.y and L1.y > B2.y) then return false end
|
||||
if (L2.z < B1.z and L1.z < B1.z) then return false end
|
||||
if (L2.z > B2.z and L1.z > B2.z) then return false end
|
||||
if (L1.x > B1.x and L1.x < B2.x and
|
||||
L1.y > B1.y and L1.y < B2.y and
|
||||
L1.z > B1.z and L1.z < B2.z)
|
||||
then
|
||||
Hit = L1;
|
||||
return true
|
||||
end
|
||||
if ( (GetIntersection( L1.x-B1.x, L2.x-B1.x, L1, L2) and InBox( Hit, B1, B2, 1 ))
|
||||
or (GetIntersection( L1.y-B1.y, L2.y-B1.y, L1, L2) and InBox( Hit, B1, B2, 2 ))
|
||||
or (GetIntersection( L1.z-B1.z, L2.z-B1.z, L1, L2) and InBox( Hit, B1, B2, 3 ))
|
||||
or (GetIntersection( L1.x-B2.x, L2.x-B2.x, L1, L2) and InBox( Hit, B1, B2, 1 ))
|
||||
or (GetIntersection( L1.y-B2.y, L2.y-B2.y, L1, L2) and InBox( Hit, B1, B2, 2 ))
|
||||
or (GetIntersection( L1.z-B2.z, L2.z-B2.z, L1, L2) and InBox( Hit, B1, B2, 3 )))
|
||||
then
|
||||
return true
|
||||
end
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
local function CheckLineNear(line, pos, distance)
|
||||
local nx = 0.5
|
||||
if line.finish.x < line.start.x then nx = -nx end
|
||||
local ny = 0.5
|
||||
if line.finish.y < line.start.y then ny = -ny end
|
||||
local nz = 0.5
|
||||
if line.finish.z < line.start.z then nz = -nz end
|
||||
|
||||
for x=line.start.x,line.finish.x,nx do
|
||||
for y=line.start.y,line.finish.y,ny do
|
||||
for z=line.start.z,line.finish.z,nz do
|
||||
if vector.distance({x=x, y=y, z=z}, pos) <= distance then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local objs = minetest.get_objects_inside_radius(line.middle, (math.ceil(vector.distance(line.middle, line.start)) + math.ceil(vector.distance(line.middle, line.finish)) * 2) + 6)
|
||||
for k, obj in pairs(objs) do
|
||||
local bb = obj:get_properties().collisionbox
|
||||
-- If bb collides with line...
|
||||
local b1 = vector.add(obj:getpos(), {x=bb[1], y=bb[2], z=bb[3]})
|
||||
local b2 = vector.add(obj:getpos(), {x=bb[4], y=bb[5], z=bb[6]})
|
||||
if CheckLineBox(b1, b2, line.start, line.finish) or CheckLineNear(line, obj:getpos(), 1) then
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name ~= name and not safe_ents[obj:get_luaentity().name] then
|
||||
if def.hit_object(self, obj:getpos(), obj) then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
elseif obj:is_player() then
|
||||
local can = true
|
||||
if self.timer > 0.2 or not self.player or obj:get_player_name() ~= self.player:get_player_name() then
|
||||
if def.hit_player(self, obj:getpos(), obj) then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local hitnode = nil
|
||||
|
||||
for pos in rayIter(line.start, self.object:getvelocity(), vector.distance(line.start, line.finish)) do
|
||||
local node = minetest.get_node(pos)
|
||||
if def.is_passthrough_node(self, pos, node) then
|
||||
self.lastair = pos
|
||||
else
|
||||
hitnode = pos
|
||||
end
|
||||
end
|
||||
|
||||
if hitnode then
|
||||
if def.hit_node(self, hitnode, self.lastair) then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
|
||||
end
|
||||
|
||||
minetest.register_entity(name, ent_def)
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
wtfpl licenses
|
||||
2015 by Glünggi
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,125 @@
|
|||
-- refruit for minetest
|
||||
-- makes fruits regrowing on the trees.
|
||||
-- images and code are WTFPL license (2015 by Glünggi)
|
||||
refruit = {}
|
||||
|
||||
--replacement
|
||||
minetest.register_node(":default:apple", {
|
||||
description = "Apple",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = {"default_apple.png"},
|
||||
inventory_image = "default_apple.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
|
||||
},
|
||||
groups = {fleshy=3,dig_immediate=3,flammable=2,leafdecay=3,leafdecay_drop=1},
|
||||
on_use = minetest.item_eat(2),
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
if placer:is_player() then
|
||||
minetest.set_node(pos, {name="default:apple", param2=1})
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldnode.name == "default:apple" then
|
||||
if oldnode.param2 ~= 0 then
|
||||
return
|
||||
end
|
||||
minetest.set_node(pos,{name = "refruit:bud_apple"})
|
||||
else
|
||||
return
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--register nodes
|
||||
|
||||
minetest.register_node("refruit:bud_apple", {
|
||||
description = "Apple Bud",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = {"refruit_bud_apple.png"},
|
||||
inventory_image = "refruit_bud_apple.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.1875, -0.3125, -0.1875, 0.1875, 0.3125, 0.1875}
|
||||
},
|
||||
groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2,leafdecay=3,leafdecay_drop=1,fruit=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{
|
||||
items = {'default:stick'},
|
||||
rarity = 99,
|
||||
},
|
||||
{
|
||||
items = {'default:stick'},
|
||||
rarity = 99
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("refruit:flower_apple", {
|
||||
description = "Apple Flower",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = {"refruit_flower_apple.png"},
|
||||
inventory_image = "refruit_flower_apple.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.1875, -0.3125, -0.1875, 0.1875, 0.3125, 0.1875}
|
||||
},
|
||||
groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2,leafdecay=3,leafdecay_drop=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{
|
||||
items = {'default:stick'},
|
||||
rarity = 99,
|
||||
},
|
||||
{
|
||||
items = {'default:stick'},
|
||||
rarity = 99
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"refruit:bud_apple"},
|
||||
neighbors = {"group:leaves"},
|
||||
interval = 34,
|
||||
chance = 10,
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="refruit:flower_apple"})
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"refruit:flower_apple"},
|
||||
neighbors = {"group:leaves"},
|
||||
interval = 33,
|
||||
chance = 60,
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="default:apple"})
|
||||
end,
|
||||
})
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |