fixes
|
@ -299,6 +299,7 @@ for i = 1, #aquaz.coral_deco do
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {aquaz.coral_deco[i].tile},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = aquaz.coral_deco[i].tile,
|
||||
wield_image = aquaz.coral_deco[i].tile,
|
||||
node_box = {
|
||||
|
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
@ -248,6 +248,7 @@ end)
|
|||
function closet.register_container(name, d)
|
||||
local def = table.copy(d)
|
||||
def.drawtype = 'mesh'
|
||||
def.use_texture_alpha = true
|
||||
def.paramtype = "light"
|
||||
def.paramtype2 = "facedir"
|
||||
def.is_ground_content = false
|
||||
|
|
|
@ -7,6 +7,7 @@ closet.register_container("closet", {
|
|||
tiles = {
|
||||
"closet_closet.png",
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/2, -1/2, 0.062500, 1/2, 1.5, 1/2 },
|
||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,8 @@
|
|||
# Blossom Hedges
|
||||
|
||||
Beautiful hedges made from flowers
|
||||
|
||||
## Licenses
|
||||
|
||||
- Code: GPL v3.0
|
||||
- Textures: CC BY-SA 4.0
|
|
@ -0,0 +1,69 @@
|
|||
-- Blossom Hedges
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local hedges = {
|
||||
{
|
||||
"white_blue",
|
||||
S("White & Blue"),
|
||||
{"flowers:dandelion_white", "flowers:geranium"}
|
||||
},
|
||||
{
|
||||
"violet_blue",
|
||||
S("Violet & Blue"),
|
||||
{"flowers:viola", "flowers:geranium"}
|
||||
},
|
||||
{
|
||||
"red_pink",
|
||||
S("Red & Pink"),
|
||||
{"default:rose_bush", "flowers:geranium"}
|
||||
},
|
||||
{
|
||||
"yellow_orange",
|
||||
S("Yellow & Orange"),
|
||||
{"flowers:dandelion_yellow", "flowers:gerbera_daisy"}
|
||||
}
|
||||
}
|
||||
|
||||
local function add_hedge(name, desc, recipe_items)
|
||||
|
||||
local node_name = "blossom_hedges:" .. name.."".."hedge"
|
||||
|
||||
local drop_items = recipe_items
|
||||
|
||||
recipe_items[#recipe_items+1] = "group:leaves"
|
||||
|
||||
minetest.register_node(node_name, {
|
||||
description = S("@1 Hedge", desc),
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"flowers_" .. name .. "_hedge" .. ".png"},
|
||||
wield_image = "flowers_" .. name .. "_hedge" .. ".png",
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 3, flammable = 2, flower = 1, flora = 1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{
|
||||
items = drop_items,
|
||||
rarity = 1,
|
||||
inherit_color = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = node_name,
|
||||
type = "shapeless",
|
||||
recipe = recipe_items,
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
for _,item in pairs(hedges) do
|
||||
add_hedge(unpack(item))
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# textdomain: blossom_hedges
|
||||
@1 Hedge=Seto @1
|
||||
White & Blue=blanquiazul
|
||||
Violet & Blue=violeta azulado
|
||||
Yellow & Orange=amarillo anaranjado
|
||||
Red & Pink=rojo rosáceo
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
name = blossom_hedges
|
||||
description = Beautiful hedges made from flowers
|
||||
depends = flowers
|
||||
optional_depends =
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -141,6 +141,7 @@ minetest.register_node("baldcypress:dry_branches", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"baldcypress_dry_branches.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "baldcypress_dry_branches.png",
|
||||
wield_image = "baldcypress_dry_branches.png",
|
||||
node_box = {
|
||||
|
@ -160,6 +161,7 @@ minetest.register_node("baldcypress:liana", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"baldcypress_liana.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "baldcypress_liana.png",
|
||||
wield_image = "baldcypress_liana.png",
|
||||
is_ground_content = false,
|
||||
|
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 887 B After Width: | Height: | Size: 3.0 KiB |
|
@ -147,6 +147,7 @@ minetest.register_node("ebony:creeper", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"ebony_creeper.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "ebony_creeper.png",
|
||||
wield_image = "ebony_creeper.png",
|
||||
node_box = {
|
||||
|
@ -166,6 +167,7 @@ minetest.register_node("ebony:creeper_leaves", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"ebony_creeper_leaves.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "ebony_creeper_leaves.png",
|
||||
wield_image = "ebony_creeper_leaves.png",
|
||||
node_box = {
|
||||
|
@ -185,6 +187,7 @@ minetest.register_node("ebony:liana", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"ebony_liana.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "ebony_liana.png",
|
||||
wield_image = "ebony_liana.png",
|
||||
node_box = {
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.6 KiB |
|
@ -141,6 +141,7 @@ minetest.register_node("larch:moss", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"larch_moss.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "larch_moss.png",
|
||||
wield_image = "larch_moss.png",
|
||||
node_box = {
|
||||
|
|
|
@ -147,6 +147,7 @@ minetest.register_node("mahogany:creeper", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"mahogany_creeper.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "mahogany_creeper.png",
|
||||
wield_image = "mahogany_creeper.png",
|
||||
node_box = {
|
||||
|
@ -166,6 +167,7 @@ minetest.register_node("mahogany:flower_creeper", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"mahogany_flower_creeper.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "mahogany_flower_creeper.png",
|
||||
wield_image = "mahogany_flower_creeper.png",
|
||||
node_box = {
|
||||
|
@ -185,6 +187,7 @@ minetest.register_node("mahogany:hanging_creeper", {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"mahogany_hanging_creeper.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "mahogany_hanging_creeper.png",
|
||||
wield_image = "mahogany_hanging_creeper.png",
|
||||
node_box = {
|
||||
|
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,260 @@
|
|||
--
|
||||
-- Plumtree
|
||||
--
|
||||
local modname = "plumtree"
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
local fruit_grow_time = 1200
|
||||
|
||||
-- internationalization boilerplate
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
-- Plum Fruit
|
||||
|
||||
minetest.register_node("plumtree:plum", {
|
||||
description = S("Plum"),
|
||||
drawtype = "plantlike",
|
||||
tiles = {"plumtree_plum.png"},
|
||||
inventory_image = "plumtree_plum.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-3 / 16, -7 / 16, -3 / 16, 3 / 16, 4 / 16, 3 / 16}
|
||||
},
|
||||
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)
|
||||
minetest.set_node(pos, {name = "plumtree:plum", param2 = 1})
|
||||
end,
|
||||
|
||||
on_dig = function(pos, node, digger)
|
||||
if digger:is_player() then
|
||||
local inv = digger:get_inventory()
|
||||
if inv:room_for_item("main", "plumtree:plum") then
|
||||
inv:add_item("main", "plumtree:plum")
|
||||
end
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
pos.y = pos.y + 1
|
||||
local node_above = minetest.get_node_or_nil(pos)
|
||||
if node_above and node_above.param2 == 0 and node_above.name == "plumtree:blossom_leaves" then
|
||||
--20% of variation on time
|
||||
local twenty_percent = fruit_grow_time * 0.2
|
||||
local grow_time = math.random(fruit_grow_time - twenty_percent, fruit_grow_time + twenty_percent)
|
||||
minetest.get_node_timer(pos):start(grow_time)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Plumtree
|
||||
|
||||
local function grow_new_plumtree_tree(pos)
|
||||
if not default.can_grow(pos) then
|
||||
-- try a bit later again
|
||||
minetest.get_node_timer(pos):start(math.random(240, 600))
|
||||
return
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
minetest.place_schematic({x = pos.x-4, y = pos.y-1, z = pos.z-4}, modpath.."/schematics/plumtree.mts", "0", nil, true)
|
||||
end
|
||||
|
||||
--
|
||||
-- Decoration
|
||||
--
|
||||
|
||||
if mg_name ~= "v6" and mg_name ~= "singlenode" then
|
||||
|
||||
local place_on
|
||||
local biomes
|
||||
local offset
|
||||
local scale
|
||||
|
||||
if minetest.get_modpath("rainf") then
|
||||
place_on = "rainf:meadow"
|
||||
biomes = "rainf"
|
||||
offset = 0.0008
|
||||
scale = 0.00004
|
||||
else
|
||||
place_on = "default:dirt_with_grass"
|
||||
biomes = "grassland"
|
||||
offset = 0.00005
|
||||
scale = 0.00004
|
||||
end
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = {place_on},
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = offset,
|
||||
scale = scale,
|
||||
spread = {x = 250, y = 250, z = 250},
|
||||
seed = 23278,
|
||||
octaves = 3,
|
||||
persist = 0.66
|
||||
},
|
||||
biomes = {biomes},
|
||||
y_min = 1,
|
||||
y_max = 80,
|
||||
schematic = modpath.."/schematics/plumtree.mts",
|
||||
flags = "place_center_x, place_center_z, force_placement",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
|
||||
--
|
||||
-- Nodes
|
||||
--
|
||||
|
||||
minetest.register_node("plumtree:sapling", {
|
||||
description = S("Plumtree Tree Sapling"),
|
||||
drawtype = "plantlike",
|
||||
tiles = {"plumtree_sapling.png"},
|
||||
inventory_image = "plumtree_sapling.png",
|
||||
wield_image = "plumtree_sapling.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
on_timer = grow_new_plumtree_tree,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16}
|
||||
},
|
||||
groups = {snappy = 2, dig_immediate = 3, flammable = 2,
|
||||
attached_node = 1, sapling = 1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
on_construct = function(pos)
|
||||
minetest.get_node_timer(pos):start(math.random(2400,4800))
|
||||
end,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
itemstack = default.sapling_on_place(itemstack, placer, pointed_thing,
|
||||
"plumtree:sapling",
|
||||
-- minp, maxp to be checked, relative to sapling pos
|
||||
-- minp_relative.y = 1 because sapling pos has been checked
|
||||
{x = -2, y = 1, z = -2},
|
||||
{x = 2, y = 6, z = 2},
|
||||
-- maximum interval of interior volume check
|
||||
4)
|
||||
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("plumtree:trunk", {
|
||||
description = S("Plumtree Trunk"),
|
||||
tiles = {
|
||||
"plumtree_trunk_top.png",
|
||||
"plumtree_trunk_top.png",
|
||||
"plumtree_trunk.png"
|
||||
},
|
||||
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
on_place = minetest.rotate_node,
|
||||
})
|
||||
|
||||
-- plumtree wood
|
||||
minetest.register_node("plumtree:wood", {
|
||||
description = S("Plumtree Wood"),
|
||||
tiles = {"plumtree_wood.png"},
|
||||
paramtype2 = "facedir",
|
||||
place_param2 = 0,
|
||||
is_ground_content = false,
|
||||
groups = {wood = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 3},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
-- plumtree tree leaves
|
||||
minetest.register_node("plumtree:leaves", {
|
||||
description = S("Plumtree Leaves"),
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"plumtree_leaves.png"},
|
||||
inventory_image = "plumtree_leaves.png",
|
||||
wield_image = "plumtree_leaves.png",
|
||||
paramtype = "light",
|
||||
walkable = true,
|
||||
waving = 1,
|
||||
groups = {snappy = 3, leafdecay = 3, leaves = 1, flammable = 2},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {"plumtree:sapling"}, rarity = 20},
|
||||
{items = {"plumtree:leaves"}}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
after_place_node = default.after_place_leaves,
|
||||
})
|
||||
|
||||
--
|
||||
-- Craftitems
|
||||
--
|
||||
|
||||
--
|
||||
-- Recipes
|
||||
--
|
||||
|
||||
minetest.register_craft({
|
||||
output = "plumtree:wood 4",
|
||||
recipe = {{"plumtree:trunk"}}
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "plumtree:trunk",
|
||||
burntime = 30,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "plumtree:wood",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_lbm({
|
||||
name = "plumtree:convert_plumtree_saplings_to_node_timer",
|
||||
nodenames = {"plumtree:sapling"},
|
||||
action = function(pos)
|
||||
minetest.get_node_timer(pos):start(math.random(1200, 2400))
|
||||
end
|
||||
})
|
||||
|
||||
default.register_leafdecay({
|
||||
trunks = {"plumtree:trunk"},
|
||||
leaves = {"plumtree:leaves"},
|
||||
radius = 3,
|
||||
})
|
||||
|
||||
--Stairs
|
||||
|
||||
if minetest.get_modpath("stairs") ~= nil then
|
||||
stairs.register_stair_and_slab(
|
||||
"plumtree_trunk",
|
||||
"plumtree:trunk",
|
||||
{choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
|
||||
{"plumtree_wood.png"},
|
||||
S("Plum Tree Stair"),
|
||||
S("Plum Tree Slab"),
|
||||
default.node_sound_wood_defaults()
|
||||
)
|
||||
end
|
||||
|
||||
--Support for bonemeal
|
||||
|
||||
if minetest.get_modpath("bonemeal") ~= nil then
|
||||
bonemeal:add_sapling({
|
||||
{"plumtree:sapling", grow_new_plumtree_tree, "soil"},
|
||||
})
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# textdomain: plumtree
|
||||
Plum=Ciruela
|
||||
Plumtree Trunk=Madera de ciruelo
|
||||
Plumtree Wood=Tablas de ciruelo
|
||||
Plumtree Leaves=Hojas de ciruelo
|
||||
Plumtree Tree Sapling=Retoño de ciruelo
|
||||
Plum Tree Stair=Escaleras de ciruelo
|
||||
Plum Tree Slab=Losa de ciruelo
|
||||
Inner Plumtree Stair=Escaleras de ciruelo interior
|
||||
Outer Plumtree Stair=Escaleras de ciruelo exterior
|
||||
Plumtree Slab=Losa de ciruelo
|
|
@ -0,0 +1,4 @@
|
|||
name = plumtree
|
||||
description = Plum Tree
|
||||
depends = default
|
||||
optional_depends = stairs, bonemeal
|
|
@ -0,0 +1,883 @@
|
|||
schematic = {
|
||||
size = {x=9, y=12, z=8},
|
||||
yslice_prob = {
|
||||
{ypos=0, prob=254},
|
||||
{ypos=1, prob=254},
|
||||
{ypos=2, prob=254},
|
||||
{ypos=3, prob=254},
|
||||
{ypos=4, prob=254},
|
||||
{ypos=5, prob=254},
|
||||
{ypos=6, prob=254},
|
||||
{ypos=7, prob=254},
|
||||
{ypos=8, prob=254},
|
||||
{ypos=9, prob=254},
|
||||
{ypos=10, prob=254},
|
||||
{ypos=11, prob=254},
|
||||
},
|
||||
data = {
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=20},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=18},
|
||||
{name="plumtree:trunk", prob=254, param2=18},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=2},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=3},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:trunk", prob=254, param2=3},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:plum", prob=254, param2=1},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="plumtree:leaves", prob=254, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
{name="air", prob=0, param2=0},
|
||||
},
|
||||
}
|
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
|
@ -54,7 +54,7 @@ local function get_blastres(name, def)
|
|||
local cracky_br = { [0] = math.huge, 200, 150, 100 }
|
||||
local liquid_br = { [0] = math.huge, 200, 100, 50 }
|
||||
local level_mul = { [0] = 1, 1.5, 2.5, 5 }
|
||||
|
||||
local res
|
||||
res = math.huge
|
||||
res = math.min(res, instant_br[minetest.get_item_group(name, 'dig_immediate')])
|
||||
res = math.min(res, oddly_br[
|
||||
|
|
|
@ -6,8 +6,6 @@ chisel.group_style_index = {}
|
|||
chisel.group_style_nodes = {}
|
||||
chisel.player_copied_style = {}
|
||||
|
||||
|
||||
|
||||
chisel.register_chiselable = function(node_name, group_name, style)
|
||||
chisel.chiselable[ node_name ] = {}
|
||||
chisel.chiselable[ node_name ].group_name = group_name
|
||||
|
@ -20,8 +18,6 @@ chisel.register_chiselable = function(node_name, group_name, style)
|
|||
chisel.group_style_nodes[ group_name ][ style ] = node_name
|
||||
end
|
||||
|
||||
|
||||
|
||||
chisel.register_chiselable_stair_and_slab = function(node_subname, group_subname, style)
|
||||
chisel.register_chiselable("stairs:stair_" .. node_subname, "stairs:stair_" .. group_subname, style)
|
||||
chisel.register_chiselable("stairs:stair_inner_" .. node_subname, "stairs:stair_inner_" .. group_subname, style)
|
||||
|
@ -29,15 +25,13 @@ chisel.register_chiselable_stair_and_slab = function(node_subname, group_subname
|
|||
chisel.register_chiselable("stairs:slab_" .. node_subname, "stairs:slab_" .. group_subname, style)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function chisel_interact(player, pointed_thing, is_right_click)
|
||||
if pointed_thing.type ~= "node" then return end
|
||||
|
||||
local pos = pointed_thing.under
|
||||
local is_sneak = player and player:get_player_control().sneak or false
|
||||
local player_name = player and player:get_player_name()
|
||||
|
||||
|
||||
-- A true player is required
|
||||
if not player_name then return end
|
||||
|
||||
|
@ -56,12 +50,11 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
minetest.chat_send_player(player_name, "Not chiselable")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local group_name = chisel.chiselable[ node_name ].group_name
|
||||
local style = chisel.chiselable[ node_name ].style
|
||||
local group = chisel.group_style_nodes[ group_name ]
|
||||
local new_style , new_node_name
|
||||
|
||||
|
||||
-- Now branch on the four user-input cases
|
||||
if is_right_click then
|
||||
|
@ -77,13 +70,14 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
minetest.chat_send_player(player_name, "No chisel style copied yet, use sneak + right-click to copy a style")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Already the correct style, exit now!
|
||||
if new_style == style then return end
|
||||
|
||||
|
||||
new_node_name = group[ new_style ]
|
||||
if not new_node_name then
|
||||
minetest.chat_send_player(player_name, "Chisel style " .. new_style .. " is not supported by this chisel group " .. group_name)
|
||||
minetest.chat_send_player(player_name, "Chisel style " .. new_style ..
|
||||
" is not supported by this chisel group " .. group_name)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -95,7 +89,7 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
new_style = k
|
||||
new_node_name = v
|
||||
end
|
||||
|
||||
|
||||
if new_node_name == nil then
|
||||
-- Not found? Go for the last element
|
||||
for k,v in pairs(group) do
|
||||
|
@ -111,16 +105,16 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Check if rotation could be preserved
|
||||
local nodedef = minetest.registered_nodes[node_name]
|
||||
local new_nodedef = minetest.registered_nodes[new_node_name]
|
||||
local rotation , new_rotation
|
||||
|
||||
|
||||
if nodedef and new_nodedef then
|
||||
if ( nodedef.paramtype2 == "facedir" or nodedef.paramtype2 == "colorfacedir" ) and ( new_nodedef.paramtype2 == "facedir" or new_nodedef.paramtype2 == "colorfacedir" ) then
|
||||
rotation = node.param2 % 32 --rotation are on the last 5 digits
|
||||
if ( nodedef.paramtype2 == "facedir" or nodedef.paramtype2 == "colorfacedir" )
|
||||
and( new_nodedef.paramtype2 == "facedir" or new_nodedef.paramtype2 == "colorfacedir" ) then
|
||||
rotation = node.param2 % 32 --rotation are on the last 5 digits
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -131,7 +125,7 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
-- Copy rotation if needed!
|
||||
if rotation ~= nil then
|
||||
new_rotation = new_node.param2 % 32
|
||||
|
||||
|
||||
if new_rotation ~= rotation then
|
||||
new_node.param2 = new_node.param2 - new_rotation + rotation
|
||||
minetest.swap_node(pos, new_node)
|
||||
|
@ -141,8 +135,6 @@ local function chisel_interact(player, pointed_thing, is_right_click)
|
|||
minetest.sound_play("jonez_carve", {pos = pos, gain = 0.7, max_hear_distance = 5})
|
||||
end
|
||||
|
||||
|
||||
|
||||
--The chisel to carve the marble
|
||||
minetest.register_craftitem("jonez:chisel", {
|
||||
description = S("Chisel for Marble"),
|
||||
|
@ -158,8 +150,6 @@ minetest.register_craftitem("jonez:chisel", {
|
|||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shaped",
|
||||
output = "jonez:chisel",
|
||||
|
|
|
@ -129,11 +129,12 @@ local styles = {
|
|||
"medieval",
|
||||
"gothic",
|
||||
"pompeiian",
|
||||
"corinthian"
|
||||
"corinthian",
|
||||
"carthaginian",
|
||||
"industrial",
|
||||
"romanesque"
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- The Crafting of the Greek Set
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -176,8 +177,6 @@ minetest.register_craft({
|
|||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
for i = 1, #styles do
|
||||
|
||||
chisel.register_chiselable("jonez:"..styles[i].."_architrave", "jonez:architrave", styles[i] )
|
||||
|
@ -232,6 +231,7 @@ for i = 1, #vines do
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {vines[i].texture},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = vines[i].texture,
|
||||
wield_image = vines[i].texture,
|
||||
node_box = {
|
||||
|
@ -260,21 +260,27 @@ local panels = {
|
|||
{"dye:green", "dye:red", "dye:orange"},
|
||||
}
|
||||
},
|
||||
{name= "wrought_lattice_bottom", description= "Ancient Wrought Lattice (Bottom)",textures={front="jonez_wrought_lattice_bottom.png", edge="jonez_panes_edge.png"},
|
||||
{name= "wrought_lattice_bottom", description= "Ancient Wrought Lattice (Bottom)",
|
||||
textures={front="jonez_wrought_lattice_bottom.png", edge="jonez_panes_edge.png"},
|
||||
use_texture_alpha = true,
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'default:steel_ingot', 'default:tin_ingot', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'default:tin_ingot', 'default:steel_ingot'},
|
||||
}
|
||||
},
|
||||
{name= "palace_window_top", description= "Palace Window (Top)",textures={front="jonez_palace_window_top.png", edge="default_wood.png"},
|
||||
{name= "palace_window_top", description= "Palace Window (Top)",
|
||||
textures={front="jonez_palace_window_top.png", edge="default_wood.png"},
|
||||
use_texture_alpha = true,
|
||||
recipe = {
|
||||
{'', 'xpanes:pane_flat', ''},
|
||||
{'', 'xpanes:pane_flat', ''},
|
||||
{'', '', ''},
|
||||
}
|
||||
},
|
||||
{name= "palace_window_bottom", description= "Palace Window (Bottom)",textures={front="jonez_palace_window_bottom.png", edge="default_wood.png"},
|
||||
{name= "palace_window_bottom", description= "Palace Window (Bottom)",
|
||||
textures={front="jonez_palace_window_bottom.png", edge="default_wood.png"},
|
||||
use_texture_alpha = true,
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'', 'xpanes:pane_flat', ''},
|
||||
|
@ -287,6 +293,7 @@ for j=1, #panels do
|
|||
xpanes.register_pane(panels[j].name, {
|
||||
description = S(panels[j].description),
|
||||
textures = {panels[j].textures.front, nil, panels[j].textures.edge},
|
||||
use_texture_alpha = panels[j].use_texture_alpha,
|
||||
inventory_image = panels[j].textures.front,
|
||||
wield_image = panels[j].textures.front,
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
|
@ -375,16 +382,23 @@ local pavements= {
|
|||
},
|
||||
{name= "jonez:pompeiian_path", description= "Ancient Pompeiian Path", texture= "jonez_pompeiian_path.png", amount = 4,
|
||||
recipe = {
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished'},
|
||||
{'stairs:slab_marble_brick', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished'},
|
||||
}
|
||||
},
|
||||
{name= "jonez:pompeiian_path", description= "Ancient Pompeiian Path", texture= "jonez_pompeiian_path.png", amount = 4,
|
||||
{name= "jonez:carthaginian_pavement", description= "Carthaginian Pavement", texture= "jonez_carthaginian_pavement.png", amount = 4,
|
||||
recipe = {
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'default:gravel', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick'},
|
||||
}
|
||||
},
|
||||
{name= "jonez:carthaginian_wall", description= "Carthaginian Wall", texture= "jonez_carthaginian_wall.png", amount = 4,
|
||||
recipe = {
|
||||
{'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished'},
|
||||
{'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick'},
|
||||
{'stairs:slab_marble_brick_polished', 'stairs:slab_marble_brick', 'stairs:slab_marble_brick_polished'},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -433,6 +447,7 @@ minetest.register_node("jonez:wrought_lattice_top", {
|
|||
"jonez_wrought_lattice_top.png",
|
||||
"jonez_wrought_lattice_top.png"
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -452,7 +467,6 @@ minetest.register_node("jonez:versailles_pavement", {
|
|||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'jonez:versailles_pavement',
|
||||
type = "shaped",
|
||||
|
|
|
@ -20,6 +20,9 @@ Medieval=Medieval
|
|||
Gothic=Gótico
|
||||
Pompeiian=Pompeyano
|
||||
Corinthian=Corintio
|
||||
Carthaginian=Cartaginés
|
||||
Industrial=Industrial
|
||||
Romanesque=Romanisco
|
||||
Ancient Marble Stair=Escalera de mármol antiguo
|
||||
Ancient Marble Slab=Losa de mármol antiguo
|
||||
Ancient Marble Brick Stair=Escalera de ladrillo de mármol antiguo
|
||||
|
@ -54,3 +57,5 @@ Ancient Pompeiian Wall=Muro antiguo pompeyano
|
|||
Ancient Pompeiian Pavement=Pavimento antiguo pompeyano
|
||||
Ancient Pompeiian Path=Camino antiguo pompeyano
|
||||
Ancient Pompeiian Altar=Altar antiguo pompeyano
|
||||
Carthaginian Pavement=Pavimiento cartaginés
|
||||
Carthaginian Wall=Pavimiento cartaginés
|
||||
|
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.9 KiB |
|
@ -171,7 +171,8 @@ function boat.on_step(self, dtime)
|
|||
end
|
||||
end
|
||||
local velo = self.object:get_velocity()
|
||||
if self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
if not self.driver and
|
||||
self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
return
|
||||
end
|
||||
|
|
|
@ -307,6 +307,7 @@ local waterlily_def = {
|
|||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"},
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "flowers_waterlily.png",
|
||||
wield_image = "flowers_waterlily.png",
|
||||
liquids_pointable = true,
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
@ -0,0 +1,6 @@
|
|||
# mobkit
|
||||
Entity API for Minetest
|
||||
|
||||
This library is meant to be shared between mods</br>
|
||||
Please do not write to the mobkit namespace ('mobkit' global table),</br>
|
||||
nor include own copies of mobkit in your mods and modpacks.
|
|
@ -0,0 +1,830 @@
|
|||
local abs = math.abs
|
||||
local pi = math.pi
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local max = math.max
|
||||
local min = math.min
|
||||
local tan = math.tan
|
||||
local pow = math.pow
|
||||
local dbg = minetest.chat_send_all
|
||||
|
||||
local abr = tonumber(minetest.get_mapgen_setting('active_block_range')) or 3
|
||||
|
||||
local neighbors ={
|
||||
{x=1,z=0},
|
||||
{x=1,z=1},
|
||||
{x=0,z=1},
|
||||
{x=-1,z=1},
|
||||
{x=-1,z=0},
|
||||
{x=-1,z=-1},
|
||||
{x=0,z=-1},
|
||||
{x=1,z=-1}
|
||||
}
|
||||
|
||||
function [yournamespace].dir2neighbor(dir)
|
||||
dir.y=0
|
||||
dir=vector.round(vector.normalize(dir))
|
||||
for k,v in ipairs(neighbors) do
|
||||
if v.x == dir.x and v.z == dir.z then return k end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function [yournamespace].neighbor_shift(neighbor,shift) -- int shift: minus is left, plus is right
|
||||
return (8+neighbor+shift-1)%8+1
|
||||
end
|
||||
|
||||
function [yournamespace].is_neighbor_node_reachable(self,neighbor) -- todo: take either number or pos
|
||||
local offset = neighbors[neighbor]
|
||||
local pos=mobkit.get_stand_pos(self)
|
||||
local tpos = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
local recursteps = ceil(self.jump_height)+1
|
||||
local height, liquidflag = mobkit.get_terrain_height(tpos,recursteps)
|
||||
|
||||
if height and abs(height-pos.y) <= self.jump_height then
|
||||
tpos.y = height
|
||||
height = height - pos.y
|
||||
|
||||
-- don't cut corners
|
||||
if neighbor % 2 == 0 then -- diagonal neighbors are even
|
||||
local n2 = neighbor-1 -- left neighbor never < 0
|
||||
offset = neighbors[n2]
|
||||
local t2 = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
local h2 = mobkit.get_terrain_height(t2,recursteps)
|
||||
if h2 and h2 - pos.y > 0.02 then return end
|
||||
n2 = (neighbor+1)%8 -- right neighbor
|
||||
offset = neighbors[n2]
|
||||
t2 = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
h2 = mobkit.get_terrain_height(t2,recursteps)
|
||||
if h2 and h2 - pos.y > 0.02 then return end
|
||||
end
|
||||
|
||||
-- check headroom
|
||||
if tpos.y+self.height-pos.y > 1 then -- if head in next node above, else no point checking headroom
|
||||
local snpos = mobkit.get_node_pos(pos)
|
||||
local pos1 = {x=pos.x,y=snpos.y+1,z=pos.z} -- current pos plus node up
|
||||
local pos2 = {x=tpos.x,y=tpos.y+self.height,z=tpos.z} -- target head pos
|
||||
|
||||
local nodes = mobkit.get_nodes_in_area(pos1,pos2,true)
|
||||
|
||||
for p,node in pairs(nodes) do
|
||||
if snpos.x==p.x and snpos.z==p.z then
|
||||
if node.name=='ignore' or node.walkable then return end
|
||||
else
|
||||
if node.name=='ignore' or
|
||||
(node.walkable and mobkit.get_node_height(p)>tpos.y+0.001) then return end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return height, tpos, liquidflag
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function [yournamespace].get_next_waypoint(self,tpos)
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local dir=vector.direction(pos,tpos)
|
||||
local neighbor = [yournamespace].dir2neighbor(dir)
|
||||
local function update_pos_history(self,pos)
|
||||
table.insert(self.pos_history,1,pos)
|
||||
if #self.pos_history > 2 then table.remove(self.pos_history,#self.pos_history) end
|
||||
end
|
||||
local nogopos = self.pos_history[2]
|
||||
|
||||
local height, pos2, liquidflag = [yournamespace].is_neighbor_node_reachable(self,neighbor)
|
||||
if height and not liquidflag
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
|
||||
local heightl = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,-1))
|
||||
if heightl and abs(heightl-height)<0.001 then
|
||||
local heightr = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,1))
|
||||
if heightr and abs(heightr-height)<0.001 then
|
||||
dir.y = 0
|
||||
local dirn = vector.normalize(dir)
|
||||
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
|
||||
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
|
||||
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
|
||||
end
|
||||
end
|
||||
update_pos_history(self,pos2)
|
||||
return height, pos2
|
||||
else
|
||||
|
||||
for i=1,3 do
|
||||
-- scan left
|
||||
local height, pos2, liq = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,-i*self.path_dir))
|
||||
if height and not liq
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
-- scan right
|
||||
height, pos2, liq = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,i*self.path_dir))
|
||||
if height and not liq
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
end
|
||||
--scan rear
|
||||
height, pos2, liquidflag = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,4))
|
||||
if height and not liquidflag
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
end
|
||||
-- stuck condition here
|
||||
table.remove(self.pos_history,2)
|
||||
self.path_dir = self.path_dir*-1 -- subtle change in pathfinding
|
||||
end
|
||||
|
||||
function [yournamespace].get_next_waypoint_fast(self,tpos,nogopos)
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local dir=vector.direction(pos,tpos)
|
||||
local neighbor = [yournamespace].dir2neighbor(dir)
|
||||
local height, pos2, liquidflag = [yournamespace].is_neighbor_node_reachable(self,neighbor)
|
||||
|
||||
if height and not liquidflag then
|
||||
local fast = false
|
||||
heightl = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,-1))
|
||||
if heightl and abs(heightl-height)<0.001 then
|
||||
heightr = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,1))
|
||||
if heightr and abs(heightr-height)<0.001 then
|
||||
fast = true
|
||||
dir.y = 0
|
||||
local dirn = vector.normalize(dir)
|
||||
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
|
||||
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
|
||||
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
|
||||
end
|
||||
end
|
||||
return height, pos2, fast
|
||||
else
|
||||
|
||||
for i=1,4 do
|
||||
-- scan left
|
||||
height, pos2, liq = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,-i))
|
||||
if height and not liq then return height,pos2 end
|
||||
-- scan right
|
||||
height, pos2, liq = [yournamespace].is_neighbor_node_reachable(self,[yournamespace].neighbor_shift(neighbor,i))
|
||||
if height and not liq then return height,pos2 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function [yournamespace].goto_next_waypoint(self,tpos)
|
||||
local height, pos2 = [yournamespace].get_next_waypoint(self,tpos)
|
||||
|
||||
if not height then return false end
|
||||
|
||||
if height <= 0.01 then
|
||||
local yaw = self.object:get_yaw()
|
||||
local tyaw = minetest.dir_to_yaw(vector.direction(self.object:get_pos(),pos2))
|
||||
if abs(tyaw-yaw) > 1 then
|
||||
[yournamespace].lq_turn2pos(self,pos2)
|
||||
end
|
||||
[yournamespace].lq_dumbwalk(self,pos2)
|
||||
else
|
||||
[yournamespace].lq_turn2pos(self,pos2)
|
||||
[yournamespace].lq_dumbjump(self,height)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------
|
||||
-- BEHAVIORS
|
||||
----------------------------
|
||||
-- LOW LEVEL QUEUE FUNCTIONS
|
||||
----------------------------
|
||||
|
||||
function [yournamespace].lq_turn2pos(self,tpos)
|
||||
local func=function(self)
|
||||
local pos = self.object:get_pos()
|
||||
return mobkit.turn2yaw(self,
|
||||
minetest.dir_to_yaw(vector.direction(pos,tpos)))
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_idle(self,duration,anim)
|
||||
anim = anim or 'stand'
|
||||
local init = true
|
||||
local func=function(self)
|
||||
if init then
|
||||
mobkit.animate(self,anim)
|
||||
init=false
|
||||
end
|
||||
duration = duration-self.dtime
|
||||
if duration <= 0 then return true end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_dumbwalk(self,dest,speed_factor)
|
||||
local timer = 3 -- failsafe
|
||||
speed_factor = speed_factor or 1
|
||||
local func=function(self)
|
||||
mobkit.animate(self,'walk')
|
||||
timer = timer - self.dtime
|
||||
if timer < 0 then return true end
|
||||
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local y = self.object:get_velocity().y
|
||||
|
||||
if mobkit.is_there_yet2d(pos,minetest.yaw_to_dir(self.object:get_yaw()),dest) then
|
||||
-- if mobkit.isnear2d(pos,dest,0.25) then
|
||||
if not self.isonground or abs(dest.y-pos.y) > 0.1 then -- prevent uncontrolled fall when velocity too high
|
||||
-- if abs(dest.y-pos.y) > 0.1 then -- isonground too slow for speeds > 4
|
||||
self.object:set_velocity({x=0,y=y,z=0})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if self.isonground then
|
||||
local dir = vector.normalize(vector.direction({x=pos.x,y=0,z=pos.z},
|
||||
{x=dest.x,y=0,z=dest.z}))
|
||||
dir = vector.multiply(dir,self.max_speed*speed_factor)
|
||||
-- self.object:set_yaw(minetest.dir_to_yaw(dir))
|
||||
mobkit.turn2yaw(self,minetest.dir_to_yaw(dir))
|
||||
dir.y = y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
-- initial velocity for jump height h, v= a*sqrt(h*2/a) ,add 20%
|
||||
function [yournamespace].lq_dumbjump(self,height,anim)
|
||||
anim = anim or 'stand'
|
||||
local jump = true
|
||||
local func=function(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
if self.isonground then
|
||||
if jump then
|
||||
mobkit.animate(self,anim)
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
dir.y = -mobkit.gravity*sqrt((height+0.35)*2/-mobkit.gravity)
|
||||
self.object:set_velocity(dir)
|
||||
jump = false
|
||||
else -- the eagle has landed
|
||||
return true
|
||||
end
|
||||
else
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
local vel = self.object:get_velocity()
|
||||
if self.lastvelocity.y < 0.9 then
|
||||
dir = vector.multiply(dir,3)
|
||||
end
|
||||
dir.y = vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_jumpout(self)
|
||||
local phase = 1
|
||||
local func=function(self)
|
||||
local vel=self.object:get_velocity()
|
||||
if phase == 1 then
|
||||
vel.y=vel.y+5
|
||||
self.object:set_velocity(vel)
|
||||
phase = 2
|
||||
else
|
||||
if vel.y < 0 then return true end
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir.y=vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_freejump(self)
|
||||
local phase = 1
|
||||
local func=function(self)
|
||||
local vel=self.object:get_velocity()
|
||||
if phase == 1 then
|
||||
vel.y=vel.y+6
|
||||
self.object:set_velocity(vel)
|
||||
phase = 2
|
||||
else
|
||||
if vel.y <= 0.01 then return true end
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir.y=vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_jumpattack(self,height,target)
|
||||
local init=true
|
||||
local timer=0.5
|
||||
local tgtbox = target:get_properties().collisionbox
|
||||
local func=function(self)
|
||||
if not mobkit.is_alive(target) then return true end
|
||||
if self.isonground then
|
||||
if init then -- collision bug workaround
|
||||
local vel = self.object:get_velocity()
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir=vector.multiply(dir,6)
|
||||
dir.y = -mobkit.gravity*sqrt(height*2/-mobkit.gravity)
|
||||
self.object:set_velocity(dir)
|
||||
mobkit.make_sound(self,'charge')
|
||||
init=false
|
||||
else
|
||||
[yournamespace].lq_idle(self,0.3)
|
||||
return true
|
||||
end
|
||||
else
|
||||
local tgtpos = target:get_pos()
|
||||
local pos = self.object:get_pos()
|
||||
-- calculate attack spot
|
||||
local yaw = self.object:get_yaw()
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
local apos = mobkit.pos_translate2d(pos,yaw,self.attack.range)
|
||||
|
||||
if mobkit.is_pos_in_box(apos,tgtpos,tgtbox) then --bite
|
||||
target:punch(self.object,1,self.attack)
|
||||
-- bounce off
|
||||
local vy = self.object:get_velocity().y
|
||||
self.object:set_velocity({x=dir.x*-3,y=vy,z=dir.z*-3})
|
||||
-- play attack sound if defined
|
||||
mobkit.make_sound(self,'attack')
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function [yournamespace].lq_fallover(self)
|
||||
local zrot = 0
|
||||
local init = true
|
||||
local func=function(self)
|
||||
if init then
|
||||
local vel = self.object:get_velocity()
|
||||
self.object:set_velocity(mobkit.pos_shift(vel,{y=1}))
|
||||
mobkit.animate(self,'stand')
|
||||
init = false
|
||||
end
|
||||
zrot=zrot+pi*0.05
|
||||
local rot = self.object:get_rotation()
|
||||
self.object:set_rotation({x=rot.x,y=rot.y,z=zrot})
|
||||
if zrot >= pi*0.5 then return true end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
-----------------------------
|
||||
-- HIGH LEVEL QUEUE FUNCTIONS
|
||||
-----------------------------
|
||||
|
||||
function [yournamespace].dumbstep(self,height,tpos,speed_factor,idle_duration)
|
||||
if height <= 0.001 then
|
||||
[yournamespace].lq_turn2pos(self,tpos)
|
||||
[yournamespace].lq_dumbwalk(self,tpos,speed_factor)
|
||||
else
|
||||
[yournamespace].lq_turn2pos(self,tpos)
|
||||
[yournamespace].lq_dumbjump(self,height)
|
||||
end
|
||||
idle_duration = idle_duration or 6
|
||||
[yournamespace].lq_idle(self,random(ceil(idle_duration*0.5),idle_duration))
|
||||
end
|
||||
|
||||
function [yournamespace].hq_roam(self,prty)
|
||||
local func=function(self)
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local neighbor = random(8)
|
||||
|
||||
local height, tpos, liquidflag = [yournamespace].is_neighbor_node_reachable(self,neighbor)
|
||||
if height and not liquidflag then [yournamespace].dumbstep(self,height,tpos,0.3) end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_follow0(self,tgtobj) -- probably delete this one
|
||||
local func = function(self)
|
||||
if not tgtobj then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) > 3 then
|
||||
local neighbor = [yournamespace].dir2neighbor(vector.direction(pos,opos))
|
||||
if not neighbor then return true end --temp debug
|
||||
local height, tpos = [yournamespace].is_neighbor_node_reachable(self,neighbor)
|
||||
if height then [yournamespace].dumbstep(self,height,tpos)
|
||||
else
|
||||
for i=1,4 do --scan left
|
||||
height, tpos = [yournamespace].is_neighbor_node_reachable(self,(8+neighbor-i-1)%8+1)
|
||||
if height then [yournamespace].dumbstep(self,height,tpos)
|
||||
break
|
||||
end --scan right
|
||||
height, tpos = [yournamespace].is_neighbor_node_reachable(self,(neighbor+i-1)%8+1)
|
||||
if height then [yournamespace].dumbstep(self,height,tpos)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
[yournamespace].lq_idle(self,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,0)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_follow(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) > 3 then
|
||||
[yournamespace].goto_next_waypoint(self,opos)
|
||||
else
|
||||
[yournamespace].lq_idle(self,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_goto(self,prty,tpos)
|
||||
local func = function(self)
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
if vector.distance(pos,tpos) > 3 then
|
||||
[yournamespace].goto_next_waypoint(self,tpos)
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_runfrom(self,prty,tgtobj)
|
||||
local init=true
|
||||
local timer=6
|
||||
local func = function(self)
|
||||
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
timer = timer-self.dtime
|
||||
if timer <=0 or vector.distance(self.object:get_pos(),tgtobj:get_pos()) < 8 then
|
||||
mobkit.make_sound(self,'scared')
|
||||
init=false
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) < self.view_range*1.1 then
|
||||
local tpos = {x=2*pos.x - opos.x,
|
||||
y=opos.y,
|
||||
z=2*pos.z - opos.z}
|
||||
[yournamespace].goto_next_waypoint(self,tpos)
|
||||
else
|
||||
self.object:set_velocity({x=0,y=0,z=0})
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_hunt(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
local dist = vector.distance(pos,opos)
|
||||
if dist > self.view_range then
|
||||
return true
|
||||
elseif dist > 3 then
|
||||
[yournamespace].goto_next_waypoint(self,opos)
|
||||
else
|
||||
[yournamespace].hq_attack(self,prty+1,tgtobj)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_warn(self,prty,tgtobj)
|
||||
local timer=0
|
||||
local tgttime = 0
|
||||
local init = true
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
mobkit.animate(self,'stand')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
local dist = vector.distance(pos,opos)
|
||||
|
||||
if dist > 11 then
|
||||
return true
|
||||
elseif dist < 4 or timer > 12 then -- too close man
|
||||
-- mobkit.clear_queue_high(self)
|
||||
mobkit.remember(self,'hate',tgtobj:get_player_name())
|
||||
[yournamespace].hq_hunt(self,prty+1,tgtobj) -- priority
|
||||
else
|
||||
timer = timer+self.dtime
|
||||
if mobkit.is_queue_empty_low(self) then
|
||||
[yournamespace].lq_turn2pos(self,opos)
|
||||
end
|
||||
-- make noise in random intervals
|
||||
if timer > tgttime then
|
||||
mobkit.make_sound(self,'warn')
|
||||
-- if self.sounds and self.sounds.warn then
|
||||
-- minetest.sound_play(self.sounds.warn, {object=self.object})
|
||||
-- end
|
||||
tgttime = timer + 1.1 + random()*1.5
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_die(self)
|
||||
local timer = 5
|
||||
local start = true
|
||||
local func = function(self)
|
||||
if start then
|
||||
[yournamespace].lq_fallover(self)
|
||||
self.logic = function(self) end -- brain dead as well
|
||||
start=false
|
||||
end
|
||||
timer = timer-self.dtime
|
||||
if timer < 0 then self.object:remove() end
|
||||
end
|
||||
mobkit.queue_high(self,func,100)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_attack(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
-- local tpos = tgtobj:get_pos()
|
||||
local tpos = mobkit.get_stand_pos(tgtobj)
|
||||
local dist = vector.distance(pos,tpos)
|
||||
if dist > 3 then
|
||||
return true
|
||||
else
|
||||
[yournamespace].lq_turn2pos(self,tpos)
|
||||
local height = tgtobj:is_player() and 0.35 or tgtobj:get_luaentity().height*0.6
|
||||
if tpos.y+height>pos.y then
|
||||
[yournamespace].lq_jumpattack(self,tpos.y+height-pos.y,tgtobj)
|
||||
else
|
||||
[yournamespace].lq_dumbwalk(self,mobkit.pos_shift(tpos,{x=random()-0.5,z=random()-0.5}))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_liquid_recovery(self,prty) -- scan for nearest land
|
||||
local radius = 1
|
||||
local yaw = 0
|
||||
local func = function(self)
|
||||
if not self.isinliquid then return true end
|
||||
local pos=self.object:get_pos()
|
||||
local vec = minetest.yaw_to_dir(yaw)
|
||||
local pos2 = mobkit.pos_shift(pos,vector.multiply(vec,radius))
|
||||
local height, liquidflag = mobkit.get_terrain_height(pos2)
|
||||
if height and not liquidflag then
|
||||
[yournamespace].hq_swimto(self,prty,pos2)
|
||||
return true
|
||||
end
|
||||
yaw=yaw+pi*0.25
|
||||
if yaw>2*pi then
|
||||
yaw = 0
|
||||
radius=radius+1
|
||||
if radius > self.view_range then
|
||||
self.hp = 0
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_swimto(self,prty,tpos)
|
||||
local box = self.object:get_properties().collisionbox
|
||||
local cols = {}
|
||||
local func = function(self)
|
||||
if not self.isinliquid then
|
||||
if self.isonground then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local y=self.object:get_velocity().y
|
||||
local pos2d = {x=pos.x,y=tpos.y,z=pos.z}
|
||||
local dir=vector.normalize(vector.direction(pos2d,tpos))
|
||||
local yaw = minetest.dir_to_yaw(dir)
|
||||
|
||||
if mobkit.timer(self,1) then
|
||||
cols = mobkit.get_box_displace_cols(pos,box,dir,1)
|
||||
for _,p in ipairs(cols) do
|
||||
p.y=pos.y
|
||||
local h,l = mobkit.get_terrain_height(p)
|
||||
if h and h>pos.y and self.isinliquid then
|
||||
[yournamespace].lq_freejump(self)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif mobkit.turn2yaw(self,yaw) then
|
||||
dir.y = y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
---------------------
|
||||
-- AQUATIC
|
||||
---------------------
|
||||
|
||||
-- MACROS
|
||||
local function aqua_radar_dumb(pos,yaw,range,reverse)
|
||||
range = range or 4
|
||||
|
||||
local function okpos(p)
|
||||
local node = mobkit.nodeatpos(p)
|
||||
if node then
|
||||
if node.drawtype == 'liquid' then
|
||||
local nodeu = mobkit.nodeatpos(mobkit.pos_shift(p,{y=1}))
|
||||
local noded = mobkit.nodeatpos(mobkit.pos_shift(p,{y=-1}))
|
||||
if (nodeu and nodeu.drawtype == 'liquid') or (noded and noded.drawtype == 'liquid') then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
local h,l = mobkit.get_terrain_height(p)
|
||||
if h then
|
||||
local node2 = mobkit.nodeatpos({x=p.x,y=h+1.99,z=p.z})
|
||||
if node2 and node2.drawtype == 'liquid' then return true, h end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local fpos = mobkit.pos_translate2d(pos,yaw,range)
|
||||
local ok,h = okpos(fpos)
|
||||
if not ok then
|
||||
local ffrom, fto, fstep
|
||||
if reverse then
|
||||
ffrom, fto, fstep = 3,1,-1
|
||||
else
|
||||
ffrom, fto, fstep = 1,3,1
|
||||
end
|
||||
for i=ffrom, fto, fstep do
|
||||
local ok,h = okpos(mobkit.pos_translate2d(pos,yaw+i,range))
|
||||
if ok then return yaw+i,h end
|
||||
ok,h = okpos(mobkit.pos_translate2d(pos,yaw-i,range))
|
||||
if ok then return yaw-i,h end
|
||||
end
|
||||
return yaw+pi,h
|
||||
else
|
||||
return yaw, h
|
||||
end
|
||||
end
|
||||
|
||||
function [yournamespace].is_in_deep(target)
|
||||
if not target then return false end
|
||||
local nodepos = mobkit.get_stand_pos(target)
|
||||
local node1 = mobkit.nodeatpos(nodepos)
|
||||
nodepos.y=nodepos.y+1
|
||||
local node2 = mobkit.nodeatpos(nodepos)
|
||||
nodepos.y=nodepos.y-2
|
||||
local node3 = mobkit.nodeatpos(nodepos)
|
||||
if node1 and node2 and node3 and node1.drawtype=='liquid' and (node2.drawtype=='liquid' or node3.drawtype=='liquid') then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- HQ behaviors
|
||||
|
||||
function [yournamespace].hq_aqua_roam(self,prty,speed)
|
||||
local tyaw = 0
|
||||
local init = true
|
||||
local prvscanpos = {x=0,y=0,z=0}
|
||||
local center = self.object:get_pos()
|
||||
local func = function(self)
|
||||
if init then
|
||||
mobkit.animate(self,'def')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed))
|
||||
if not vector.equals(prvscanpos,scanpos) then
|
||||
prvscanpos=scanpos
|
||||
local nyaw,height = aqua_radar_dumb(pos,yaw,speed,true)
|
||||
if height and height > pos.y then
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y+1
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
if yaw ~= nyaw then
|
||||
tyaw=nyaw
|
||||
[yournamespace].hq_aqua_turn(self,prty+1,tyaw,speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
if mobkit.timer(self,1) then
|
||||
if vector.distance(pos,center) > abr*16*0.5 then
|
||||
tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5}))
|
||||
else
|
||||
if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end
|
||||
end
|
||||
end
|
||||
|
||||
mobkit.turn2yaw(self,tyaw,3)
|
||||
-- local yaw = self.object:get_yaw()
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_aqua_turn(self,prty,tyaw,speed)
|
||||
local func = function(self)
|
||||
local finished=mobkit.turn2yaw(self,tyaw)
|
||||
-- local yaw = self.object:get_yaw()
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
if finished then return true end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function [yournamespace].hq_aqua_attack(self,prty,tgtobj,speed)
|
||||
local tyaw = 0
|
||||
local prvscanpos = {x=0,y=0,z=0}
|
||||
local init = true
|
||||
local tgtbox = tgtobj:get_properties().collisionbox
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
mobkit.animate(self,'fast')
|
||||
mobkit.make_sound(self,'attack')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed))
|
||||
if not vector.equals(prvscanpos,scanpos) then
|
||||
prvscanpos=scanpos
|
||||
local nyaw,height = aqua_radar_dumb(pos,yaw,speed*0.5)
|
||||
if height and height > pos.y then
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y+1
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
if yaw ~= nyaw then
|
||||
tyaw=nyaw
|
||||
[yournamespace].hq_aqua_turn(self,prty+1,tyaw,speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local tpos = tgtobj:get_pos()
|
||||
local tyaw=minetest.dir_to_yaw(vector.direction(pos,tpos))
|
||||
mobkit.turn2yaw(self,tyaw,3)
|
||||
local yaw = self.object:get_yaw()
|
||||
if mobkit.timer(self,1) then
|
||||
if not [yournamespace].is_in_deep(tgtobj) then return true end
|
||||
local vel = self.object:get_velocity()
|
||||
if tpos.y>pos.y+0.5 then self.object:set_velocity({x=vel.x,y=vel.y+0.5,z=vel.z})
|
||||
elseif tpos.y<pos.y-0.5 then self.object:set_velocity({x=vel.x,y=vel.y-0.5,z=vel.z}) end
|
||||
end
|
||||
if mobkit.is_pos_in_box(mobkit.pos_translate2d(pos,yaw,self.attack.range),tpos,tgtbox) then --bite
|
||||
tgtobj:punch(self.object,1,self.attack)
|
||||
[yournamespace].hq_aqua_turn(self,prty,yaw-pi,speed)
|
||||
return true
|
||||
end
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
|
@ -0,0 +1,830 @@
|
|||
local abs = math.abs
|
||||
local pi = math.pi
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local max = math.max
|
||||
local min = math.min
|
||||
local tan = math.tan
|
||||
local pow = math.pow
|
||||
local dbg = minetest.chat_send_all
|
||||
|
||||
local abr = tonumber(minetest.get_mapgen_setting('active_block_range')) or 3
|
||||
|
||||
local neighbors ={
|
||||
{x=1,z=0},
|
||||
{x=1,z=1},
|
||||
{x=0,z=1},
|
||||
{x=-1,z=1},
|
||||
{x=-1,z=0},
|
||||
{x=-1,z=-1},
|
||||
{x=0,z=-1},
|
||||
{x=1,z=-1}
|
||||
}
|
||||
|
||||
function mobkit.dir2neighbor(dir)
|
||||
dir.y=0
|
||||
dir=vector.round(vector.normalize(dir))
|
||||
for k,v in ipairs(neighbors) do
|
||||
if v.x == dir.x and v.z == dir.z then return k end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function mobkit.neighbor_shift(neighbor,shift) -- int shift: minus is left, plus is right
|
||||
return (8+neighbor+shift-1)%8+1
|
||||
end
|
||||
|
||||
function mobkit.is_neighbor_node_reachable(self,neighbor) -- todo: take either number or pos
|
||||
local offset = neighbors[neighbor]
|
||||
local pos=mobkit.get_stand_pos(self)
|
||||
local tpos = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
local recursteps = ceil(self.jump_height)+1
|
||||
local height, liquidflag = mobkit.get_terrain_height(tpos,recursteps)
|
||||
|
||||
if height and abs(height-pos.y) <= self.jump_height then
|
||||
tpos.y = height
|
||||
height = height - pos.y
|
||||
|
||||
-- don't cut corners
|
||||
if neighbor % 2 == 0 then -- diagonal neighbors are even
|
||||
local n2 = neighbor-1 -- left neighbor never < 0
|
||||
offset = neighbors[n2]
|
||||
local t2 = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
local h2 = mobkit.get_terrain_height(t2,recursteps)
|
||||
if h2 and h2 - pos.y > 0.02 then return end
|
||||
n2 = (neighbor+1)%8 -- right neighbor
|
||||
offset = neighbors[n2]
|
||||
t2 = mobkit.get_node_pos(mobkit.pos_shift(pos,offset))
|
||||
h2 = mobkit.get_terrain_height(t2,recursteps)
|
||||
if h2 and h2 - pos.y > 0.02 then return end
|
||||
end
|
||||
|
||||
-- check headroom
|
||||
if tpos.y+self.height-pos.y > 1 then -- if head in next node above, else no point checking headroom
|
||||
local snpos = mobkit.get_node_pos(pos)
|
||||
local pos1 = {x=pos.x,y=snpos.y+1,z=pos.z} -- current pos plus node up
|
||||
local pos2 = {x=tpos.x,y=tpos.y+self.height,z=tpos.z} -- target head pos
|
||||
|
||||
local nodes = mobkit.get_nodes_in_area(pos1,pos2,true)
|
||||
|
||||
for p,node in pairs(nodes) do
|
||||
if snpos.x==p.x and snpos.z==p.z then
|
||||
if node.name=='ignore' or node.walkable then return end
|
||||
else
|
||||
if node.name=='ignore' or
|
||||
(node.walkable and mobkit.get_node_height(p)>tpos.y+0.001) then return end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return height, tpos, liquidflag
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function mobkit.get_next_waypoint(self,tpos)
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local dir=vector.direction(pos,tpos)
|
||||
local neighbor = mobkit.dir2neighbor(dir)
|
||||
local function update_pos_history(self,pos)
|
||||
table.insert(self.pos_history,1,pos)
|
||||
if #self.pos_history > 2 then table.remove(self.pos_history,#self.pos_history) end
|
||||
end
|
||||
local nogopos = self.pos_history[2]
|
||||
|
||||
local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
|
||||
if height and not liquidflag
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
|
||||
local heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1))
|
||||
if heightl and abs(heightl-height)<0.001 then
|
||||
local heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1))
|
||||
if heightr and abs(heightr-height)<0.001 then
|
||||
dir.y = 0
|
||||
local dirn = vector.normalize(dir)
|
||||
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
|
||||
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
|
||||
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
|
||||
end
|
||||
end
|
||||
update_pos_history(self,pos2)
|
||||
return height, pos2
|
||||
else
|
||||
|
||||
for i=1,3 do
|
||||
-- scan left
|
||||
local height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i*self.path_dir))
|
||||
if height and not liq
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
-- scan right
|
||||
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i*self.path_dir))
|
||||
if height and not liq
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
end
|
||||
--scan rear
|
||||
height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,4))
|
||||
if height and not liquidflag
|
||||
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
|
||||
update_pos_history(self,pos2)
|
||||
return height,pos2
|
||||
end
|
||||
end
|
||||
-- stuck condition here
|
||||
table.remove(self.pos_history,2)
|
||||
self.path_dir = self.path_dir*-1 -- subtle change in pathfinding
|
||||
end
|
||||
|
||||
function mobkit.get_next_waypoint_fast(self,tpos,nogopos)
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local dir=vector.direction(pos,tpos)
|
||||
local neighbor = mobkit.dir2neighbor(dir)
|
||||
local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
|
||||
|
||||
if height and not liquidflag then
|
||||
local fast = false
|
||||
heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1))
|
||||
if heightl and abs(heightl-height)<0.001 then
|
||||
heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1))
|
||||
if heightr and abs(heightr-height)<0.001 then
|
||||
fast = true
|
||||
dir.y = 0
|
||||
local dirn = vector.normalize(dir)
|
||||
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
|
||||
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
|
||||
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
|
||||
end
|
||||
end
|
||||
return height, pos2, fast
|
||||
else
|
||||
|
||||
for i=1,4 do
|
||||
-- scan left
|
||||
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i))
|
||||
if height and not liq then return height,pos2 end
|
||||
-- scan right
|
||||
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i))
|
||||
if height and not liq then return height,pos2 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mobkit.goto_next_waypoint(self,tpos)
|
||||
local height, pos2 = mobkit.get_next_waypoint(self,tpos)
|
||||
|
||||
if not height then return false end
|
||||
|
||||
if height <= 0.01 then
|
||||
local yaw = self.object:get_yaw()
|
||||
local tyaw = minetest.dir_to_yaw(vector.direction(self.object:get_pos(),pos2))
|
||||
if abs(tyaw-yaw) > 1 then
|
||||
mobkit.lq_turn2pos(self,pos2)
|
||||
end
|
||||
mobkit.lq_dumbwalk(self,pos2)
|
||||
else
|
||||
mobkit.lq_turn2pos(self,pos2)
|
||||
mobkit.lq_dumbjump(self,height)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------
|
||||
-- BEHAVIORS
|
||||
----------------------------
|
||||
-- LOW LEVEL QUEUE FUNCTIONS
|
||||
----------------------------
|
||||
|
||||
function mobkit.lq_turn2pos(self,tpos)
|
||||
local func=function(self)
|
||||
local pos = self.object:get_pos()
|
||||
return mobkit.turn2yaw(self,
|
||||
minetest.dir_to_yaw(vector.direction(pos,tpos)))
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_idle(self,duration,anim)
|
||||
anim = anim or 'stand'
|
||||
local init = true
|
||||
local func=function(self)
|
||||
if init then
|
||||
mobkit.animate(self,anim)
|
||||
init=false
|
||||
end
|
||||
duration = duration-self.dtime
|
||||
if duration <= 0 then return true end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_dumbwalk(self,dest,speed_factor)
|
||||
local timer = 3 -- failsafe
|
||||
speed_factor = speed_factor or 1
|
||||
local func=function(self)
|
||||
mobkit.animate(self,'walk')
|
||||
timer = timer - self.dtime
|
||||
if timer < 0 then return true end
|
||||
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local y = self.object:get_velocity().y
|
||||
|
||||
if mobkit.is_there_yet2d(pos,minetest.yaw_to_dir(self.object:get_yaw()),dest) then
|
||||
-- if mobkit.isnear2d(pos,dest,0.25) then
|
||||
if not self.isonground or abs(dest.y-pos.y) > 0.1 then -- prevent uncontrolled fall when velocity too high
|
||||
-- if abs(dest.y-pos.y) > 0.1 then -- isonground too slow for speeds > 4
|
||||
self.object:set_velocity({x=0,y=y,z=0})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if self.isonground then
|
||||
local dir = vector.normalize(vector.direction({x=pos.x,y=0,z=pos.z},
|
||||
{x=dest.x,y=0,z=dest.z}))
|
||||
dir = vector.multiply(dir,self.max_speed*speed_factor)
|
||||
-- self.object:set_yaw(minetest.dir_to_yaw(dir))
|
||||
mobkit.turn2yaw(self,minetest.dir_to_yaw(dir))
|
||||
dir.y = y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
-- initial velocity for jump height h, v= a*sqrt(h*2/a) ,add 20%
|
||||
function mobkit.lq_dumbjump(self,height,anim)
|
||||
anim = anim or 'stand'
|
||||
local jump = true
|
||||
local func=function(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
if self.isonground then
|
||||
if jump then
|
||||
mobkit.animate(self,anim)
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
dir.y = -mobkit.gravity*sqrt((height+0.35)*2/-mobkit.gravity)
|
||||
self.object:set_velocity(dir)
|
||||
jump = false
|
||||
else -- the eagle has landed
|
||||
return true
|
||||
end
|
||||
else
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
local vel = self.object:get_velocity()
|
||||
if self.lastvelocity.y < 0.9 then
|
||||
dir = vector.multiply(dir,3)
|
||||
end
|
||||
dir.y = vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_jumpout(self)
|
||||
local phase = 1
|
||||
local func=function(self)
|
||||
local vel=self.object:get_velocity()
|
||||
if phase == 1 then
|
||||
vel.y=vel.y+5
|
||||
self.object:set_velocity(vel)
|
||||
phase = 2
|
||||
else
|
||||
if vel.y < 0 then return true end
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir.y=vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_freejump(self)
|
||||
local phase = 1
|
||||
local func=function(self)
|
||||
local vel=self.object:get_velocity()
|
||||
if phase == 1 then
|
||||
vel.y=vel.y+6
|
||||
self.object:set_velocity(vel)
|
||||
phase = 2
|
||||
else
|
||||
if vel.y <= 0.01 then return true end
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir.y=vel.y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_jumpattack(self,height,target)
|
||||
local init=true
|
||||
local timer=0.5
|
||||
local tgtbox = target:get_properties().collisionbox
|
||||
local func=function(self)
|
||||
if not mobkit.is_alive(target) then return true end
|
||||
if self.isonground then
|
||||
if init then -- collision bug workaround
|
||||
local vel = self.object:get_velocity()
|
||||
local dir = minetest.yaw_to_dir(self.object:get_yaw())
|
||||
dir=vector.multiply(dir,6)
|
||||
dir.y = -mobkit.gravity*sqrt(height*2/-mobkit.gravity)
|
||||
self.object:set_velocity(dir)
|
||||
mobkit.make_sound(self,'charge')
|
||||
init=false
|
||||
else
|
||||
mobkit.lq_idle(self,0.3)
|
||||
return true
|
||||
end
|
||||
else
|
||||
local tgtpos = target:get_pos()
|
||||
local pos = self.object:get_pos()
|
||||
-- calculate attack spot
|
||||
local yaw = self.object:get_yaw()
|
||||
local dir = minetest.yaw_to_dir(yaw)
|
||||
local apos = mobkit.pos_translate2d(pos,yaw,self.attack.range)
|
||||
|
||||
if mobkit.is_pos_in_box(apos,tgtpos,tgtbox) then --bite
|
||||
target:punch(self.object,1,self.attack)
|
||||
-- bounce off
|
||||
local vy = self.object:get_velocity().y
|
||||
self.object:set_velocity({x=dir.x*-3,y=vy,z=dir.z*-3})
|
||||
-- play attack sound if defined
|
||||
mobkit.make_sound(self,'attack')
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
|
||||
function mobkit.lq_fallover(self)
|
||||
local zrot = 0
|
||||
local init = true
|
||||
local func=function(self)
|
||||
if init then
|
||||
local vel = self.object:get_velocity()
|
||||
self.object:set_velocity(mobkit.pos_shift(vel,{y=1}))
|
||||
mobkit.animate(self,'stand')
|
||||
init = false
|
||||
end
|
||||
zrot=zrot+pi*0.05
|
||||
local rot = self.object:get_rotation()
|
||||
self.object:set_rotation({x=rot.x,y=rot.y,z=zrot})
|
||||
if zrot >= pi*0.5 then return true end
|
||||
end
|
||||
mobkit.queue_low(self,func)
|
||||
end
|
||||
-----------------------------
|
||||
-- HIGH LEVEL QUEUE FUNCTIONS
|
||||
-----------------------------
|
||||
|
||||
function mobkit.dumbstep(self,height,tpos,speed_factor,idle_duration)
|
||||
if height <= 0.001 then
|
||||
mobkit.lq_turn2pos(self,tpos)
|
||||
mobkit.lq_dumbwalk(self,tpos,speed_factor)
|
||||
else
|
||||
mobkit.lq_turn2pos(self,tpos)
|
||||
mobkit.lq_dumbjump(self,height)
|
||||
end
|
||||
idle_duration = idle_duration or 6
|
||||
mobkit.lq_idle(self,random(ceil(idle_duration*0.5),idle_duration))
|
||||
end
|
||||
|
||||
function mobkit.hq_roam(self,prty)
|
||||
local func=function(self)
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local neighbor = random(8)
|
||||
|
||||
local height, tpos, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
|
||||
if height and not liquidflag then mobkit.dumbstep(self,height,tpos,0.3) end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_follow0(self,tgtobj) -- probably delete this one
|
||||
local func = function(self)
|
||||
if not tgtobj then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) > 3 then
|
||||
local neighbor = mobkit.dir2neighbor(vector.direction(pos,opos))
|
||||
if not neighbor then return true end --temp debug
|
||||
local height, tpos = mobkit.is_neighbor_node_reachable(self,neighbor)
|
||||
if height then mobkit.dumbstep(self,height,tpos)
|
||||
else
|
||||
for i=1,4 do --scan left
|
||||
height, tpos = mobkit.is_neighbor_node_reachable(self,(8+neighbor-i-1)%8+1)
|
||||
if height then mobkit.dumbstep(self,height,tpos)
|
||||
break
|
||||
end --scan right
|
||||
height, tpos = mobkit.is_neighbor_node_reachable(self,(neighbor+i-1)%8+1)
|
||||
if height then mobkit.dumbstep(self,height,tpos)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
mobkit.lq_idle(self,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,0)
|
||||
end
|
||||
|
||||
function mobkit.hq_follow(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) > 3 then
|
||||
mobkit.goto_next_waypoint(self,opos)
|
||||
else
|
||||
mobkit.lq_idle(self,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_goto(self,prty,tpos)
|
||||
local func = function(self)
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
if vector.distance(pos,tpos) > 3 then
|
||||
mobkit.goto_next_waypoint(self,tpos)
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_runfrom(self,prty,tgtobj)
|
||||
local init=true
|
||||
local timer=6
|
||||
local func = function(self)
|
||||
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
timer = timer-self.dtime
|
||||
if timer <=0 or vector.distance(self.object:get_pos(),tgtobj:get_pos()) < 8 then
|
||||
mobkit.make_sound(self,'scared')
|
||||
init=false
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
if vector.distance(pos,opos) < self.view_range*1.1 then
|
||||
local tpos = {x=2*pos.x - opos.x,
|
||||
y=opos.y,
|
||||
z=2*pos.z - opos.z}
|
||||
mobkit.goto_next_waypoint(self,tpos)
|
||||
else
|
||||
self.object:set_velocity({x=0,y=0,z=0})
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_hunt(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) and self.isonground then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
local dist = vector.distance(pos,opos)
|
||||
if dist > self.view_range then
|
||||
return true
|
||||
elseif dist > 3 then
|
||||
mobkit.goto_next_waypoint(self,opos)
|
||||
else
|
||||
mobkit.hq_attack(self,prty+1,tgtobj)
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_warn(self,prty,tgtobj)
|
||||
local timer=0
|
||||
local tgttime = 0
|
||||
local init = true
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
mobkit.animate(self,'stand')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local opos = tgtobj:get_pos()
|
||||
local dist = vector.distance(pos,opos)
|
||||
|
||||
if dist > 11 then
|
||||
return true
|
||||
elseif dist < 4 or timer > 12 then -- too close man
|
||||
-- mobkit.clear_queue_high(self)
|
||||
mobkit.remember(self,'hate',tgtobj:get_player_name())
|
||||
mobkit.hq_hunt(self,prty+1,tgtobj) -- priority
|
||||
else
|
||||
timer = timer+self.dtime
|
||||
if mobkit.is_queue_empty_low(self) then
|
||||
mobkit.lq_turn2pos(self,opos)
|
||||
end
|
||||
-- make noise in random intervals
|
||||
if timer > tgttime then
|
||||
mobkit.make_sound(self,'warn')
|
||||
-- if self.sounds and self.sounds.warn then
|
||||
-- minetest.sound_play(self.sounds.warn, {object=self.object})
|
||||
-- end
|
||||
tgttime = timer + 1.1 + random()*1.5
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_die(self)
|
||||
local timer = 5
|
||||
local start = true
|
||||
local func = function(self)
|
||||
if start then
|
||||
mobkit.lq_fallover(self)
|
||||
self.logic = function(self) end -- brain dead as well
|
||||
start=false
|
||||
end
|
||||
timer = timer-self.dtime
|
||||
if timer < 0 then self.object:remove() end
|
||||
end
|
||||
mobkit.queue_high(self,func,100)
|
||||
end
|
||||
|
||||
function mobkit.hq_attack(self,prty,tgtobj)
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if mobkit.is_queue_empty_low(self) then
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
-- local tpos = tgtobj:get_pos()
|
||||
local tpos = mobkit.get_stand_pos(tgtobj)
|
||||
local dist = vector.distance(pos,tpos)
|
||||
if dist > 3 then
|
||||
return true
|
||||
else
|
||||
mobkit.lq_turn2pos(self,tpos)
|
||||
local height = tgtobj:is_player() and 0.35 or tgtobj:get_luaentity().height*0.6
|
||||
if tpos.y+height>pos.y then
|
||||
mobkit.lq_jumpattack(self,tpos.y+height-pos.y,tgtobj)
|
||||
else
|
||||
mobkit.lq_dumbwalk(self,mobkit.pos_shift(tpos,{x=random()-0.5,z=random()-0.5}))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_liquid_recovery(self,prty) -- scan for nearest land
|
||||
local radius = 1
|
||||
local yaw = 0
|
||||
local func = function(self)
|
||||
if not self.isinliquid then return true end
|
||||
local pos=self.object:get_pos()
|
||||
local vec = minetest.yaw_to_dir(yaw)
|
||||
local pos2 = mobkit.pos_shift(pos,vector.multiply(vec,radius))
|
||||
local height, liquidflag = mobkit.get_terrain_height(pos2)
|
||||
if height and not liquidflag then
|
||||
mobkit.hq_swimto(self,prty,pos2)
|
||||
return true
|
||||
end
|
||||
yaw=yaw+pi*0.25
|
||||
if yaw>2*pi then
|
||||
yaw = 0
|
||||
radius=radius+1
|
||||
if radius > self.view_range then
|
||||
self.hp = 0
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_swimto(self,prty,tpos)
|
||||
local box = self.object:get_properties().collisionbox
|
||||
local cols = {}
|
||||
local func = function(self)
|
||||
if not self.isinliquid then
|
||||
if self.isonground then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local y=self.object:get_velocity().y
|
||||
local pos2d = {x=pos.x,y=tpos.y,z=pos.z}
|
||||
local dir=vector.normalize(vector.direction(pos2d,tpos))
|
||||
local yaw = minetest.dir_to_yaw(dir)
|
||||
|
||||
if mobkit.timer(self,1) then
|
||||
cols = mobkit.get_box_displace_cols(pos,box,dir,1)
|
||||
for _,p in ipairs(cols) do
|
||||
p.y=pos.y
|
||||
local h,l = mobkit.get_terrain_height(p)
|
||||
if h and h>pos.y and self.isinliquid then
|
||||
mobkit.lq_freejump(self)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif mobkit.turn2yaw(self,yaw) then
|
||||
dir.y = y
|
||||
self.object:set_velocity(dir)
|
||||
end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
---------------------
|
||||
-- AQUATIC
|
||||
---------------------
|
||||
|
||||
-- MACROS
|
||||
local function aqua_radar_dumb(pos,yaw,range,reverse)
|
||||
range = range or 4
|
||||
|
||||
local function okpos(p)
|
||||
local node = mobkit.nodeatpos(p)
|
||||
if node then
|
||||
if node.drawtype == 'liquid' then
|
||||
local nodeu = mobkit.nodeatpos(mobkit.pos_shift(p,{y=1}))
|
||||
local noded = mobkit.nodeatpos(mobkit.pos_shift(p,{y=-1}))
|
||||
if (nodeu and nodeu.drawtype == 'liquid') or (noded and noded.drawtype == 'liquid') then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
local h,l = mobkit.get_terrain_height(p)
|
||||
if h then
|
||||
local node2 = mobkit.nodeatpos({x=p.x,y=h+1.99,z=p.z})
|
||||
if node2 and node2.drawtype == 'liquid' then return true, h end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local fpos = mobkit.pos_translate2d(pos,yaw,range)
|
||||
local ok,h = okpos(fpos)
|
||||
if not ok then
|
||||
local ffrom, fto, fstep
|
||||
if reverse then
|
||||
ffrom, fto, fstep = 3,1,-1
|
||||
else
|
||||
ffrom, fto, fstep = 1,3,1
|
||||
end
|
||||
for i=ffrom, fto, fstep do
|
||||
local ok,h = okpos(mobkit.pos_translate2d(pos,yaw+i,range))
|
||||
if ok then return yaw+i,h end
|
||||
ok,h = okpos(mobkit.pos_translate2d(pos,yaw-i,range))
|
||||
if ok then return yaw-i,h end
|
||||
end
|
||||
return yaw+pi,h
|
||||
else
|
||||
return yaw, h
|
||||
end
|
||||
end
|
||||
|
||||
function mobkit.is_in_deep(target)
|
||||
if not target then return false end
|
||||
local nodepos = mobkit.get_stand_pos(target)
|
||||
local node1 = mobkit.nodeatpos(nodepos)
|
||||
nodepos.y=nodepos.y+1
|
||||
local node2 = mobkit.nodeatpos(nodepos)
|
||||
nodepos.y=nodepos.y-2
|
||||
local node3 = mobkit.nodeatpos(nodepos)
|
||||
if node1 and node2 and node3 and node1.drawtype=='liquid' and (node2.drawtype=='liquid' or node3.drawtype=='liquid') then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- HQ behaviors
|
||||
|
||||
function mobkit.hq_aqua_roam(self,prty,speed)
|
||||
local tyaw = 0
|
||||
local init = true
|
||||
local prvscanpos = {x=0,y=0,z=0}
|
||||
local center = self.object:get_pos()
|
||||
local func = function(self)
|
||||
if init then
|
||||
mobkit.animate(self,'def')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed))
|
||||
if not vector.equals(prvscanpos,scanpos) then
|
||||
prvscanpos=scanpos
|
||||
local nyaw,height = aqua_radar_dumb(pos,yaw,speed,true)
|
||||
if height and height > pos.y then
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y+1
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
if yaw ~= nyaw then
|
||||
tyaw=nyaw
|
||||
mobkit.hq_aqua_turn(self,prty+1,tyaw,speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
if mobkit.timer(self,1) then
|
||||
if vector.distance(pos,center) > abr*16*0.5 then
|
||||
tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5}))
|
||||
else
|
||||
if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end
|
||||
end
|
||||
end
|
||||
|
||||
mobkit.turn2yaw(self,tyaw,3)
|
||||
-- local yaw = self.object:get_yaw()
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_aqua_turn(self,prty,tyaw,speed)
|
||||
local func = function(self)
|
||||
local finished=mobkit.turn2yaw(self,tyaw)
|
||||
-- local yaw = self.object:get_yaw()
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
if finished then return true end
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
||||
|
||||
function mobkit.hq_aqua_attack(self,prty,tgtobj,speed)
|
||||
local tyaw = 0
|
||||
local prvscanpos = {x=0,y=0,z=0}
|
||||
local init = true
|
||||
local tgtbox = tgtobj:get_properties().collisionbox
|
||||
local func = function(self)
|
||||
if not mobkit.is_alive(tgtobj) then return true end
|
||||
if init then
|
||||
mobkit.animate(self,'fast')
|
||||
mobkit.make_sound(self,'attack')
|
||||
init = false
|
||||
end
|
||||
local pos = mobkit.get_stand_pos(self)
|
||||
local yaw = self.object:get_yaw()
|
||||
local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed))
|
||||
if not vector.equals(prvscanpos,scanpos) then
|
||||
prvscanpos=scanpos
|
||||
local nyaw,height = aqua_radar_dumb(pos,yaw,speed*0.5)
|
||||
if height and height > pos.y then
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y+1
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
if yaw ~= nyaw then
|
||||
tyaw=nyaw
|
||||
mobkit.hq_aqua_turn(self,prty+1,tyaw,speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local tpos = tgtobj:get_pos()
|
||||
local tyaw=minetest.dir_to_yaw(vector.direction(pos,tpos))
|
||||
mobkit.turn2yaw(self,tyaw,3)
|
||||
local yaw = self.object:get_yaw()
|
||||
if mobkit.timer(self,1) then
|
||||
if not mobkit.is_in_deep(tgtobj) then return true end
|
||||
local vel = self.object:get_velocity()
|
||||
if tpos.y>pos.y+0.5 then self.object:set_velocity({x=vel.x,y=vel.y+0.5,z=vel.z})
|
||||
elseif tpos.y<pos.y-0.5 then self.object:set_velocity({x=vel.x,y=vel.y-0.5,z=vel.z}) end
|
||||
end
|
||||
if mobkit.is_pos_in_box(mobkit.pos_translate2d(pos,yaw,self.attack.range),tpos,tgtbox) then --bite
|
||||
tgtobj:punch(self.object,1,self.attack)
|
||||
mobkit.hq_aqua_turn(self,prty,yaw-pi,speed)
|
||||
return true
|
||||
end
|
||||
mobkit.go_forward_horizontal(self,speed)
|
||||
end
|
||||
mobkit.queue_high(self,func,prty)
|
||||
end
|
|
@ -5,6 +5,7 @@ Contents
|
|||
1.1.1 Low level functions
|
||||
1.1.2 High level functions
|
||||
1.1.2.1 Priority
|
||||
1.1.3 Modifying built in behaviors
|
||||
1.2 Logic function
|
||||
1.3 Processing diagram
|
||||
1.4 Entity definition
|
||||
|
@ -37,8 +38,9 @@ They signal finished state by returning true, therefore it's very important to c
|
|||
For a behavior to begin executing it has to be put on a queue. There are two separate queues, one for low and one for high level behaviors.
|
||||
Queuing is covered by behavour defining conventions
|
||||
|
||||
!!! In simplest scenarios there's no need to code behaviors, much can be achieved using only built-in stuff !!!
|
||||
!!! To start using the api it's enough to learn defining mobs and writing brain functions !!!
|
||||
Mobkit comes with some example behavior functions, which are located in /example_behaviors.lua
|
||||
!!! In simplest scenarios there's no need to code behaviors, much can be achieved using only built-in stuff !!!
|
||||
!!! To start using the api it's enough to learn defining mobs and writing brain functions !!!
|
||||
|
||||
|
||||
1.1.1 Low level behavior functions
|
||||
|
@ -99,6 +101,10 @@ hq_bhv1(self,prty):
|
|||
|
||||
Particular prioritization scheme is to be designed by the user according to specific mod requirements.
|
||||
|
||||
1.1.3 Modifying built in behaviors
|
||||
|
||||
Do not modify example_behaviors.lua directly, because functions defined there are meant to be shared between mods.
|
||||
Instead, copy the contents of /behaviors2override.lua into your mod/game, changing every occurence of the string '[yournamespace]' to the name of a lua table representing your namespace of choice.
|
||||
|
||||
1.2 Logic function
|
||||
------------------
|
||||
|
@ -138,22 +144,22 @@ end
|
|||
----------------------
|
||||
|
||||
---------------------------------------
|
||||
| PHYSICS |
|
||||
| |
|
||||
| ----------------------- |
|
||||
| | Logic Function | |
|
||||
| ----------------------- |
|
||||
| | |
|
||||
| -----|----------------- |
|
||||
| | V HL Queue | |
|
||||
| | | 1 | 2 | 3 |... | |
|
||||
| ----------------------- |
|
||||
| | |
|
||||
| -----|----------------- |
|
||||
| | V LL Queue | |
|
||||
| | | 1 | 2 | 3 |... | |
|
||||
| ----------------------- |
|
||||
| |
|
||||
| PHYSICS |
|
||||
| |
|
||||
| ----------------------- |
|
||||
| | Logic Function | |
|
||||
| ----------------------- |
|
||||
| | |
|
||||
| -----|----------------- |
|
||||
| | V HL Queue| |
|
||||
| | 1| 2| 3|... | |
|
||||
| ----------------------- |
|
||||
| | |
|
||||
| -----|----------------- |
|
||||
| | V LL Queue| |
|
||||
| | 1| 2| 3|... | |
|
||||
| ----------------------- |
|
||||
| |
|
||||
---------------------------------------
|
||||
|
||||
Order of execution during an engine step:
|
||||
|
@ -250,7 +256,7 @@ Some frequently used entity fields to be accessed directly for convenience
|
|||
|
||||
self.dtime -- max(dtime as passed to on_step,0.5) - limit of 0.05 to prevent jerkines on long steps.
|
||||
self.hp -- hitpoints
|
||||
self.isonground -- true if pos.y remains unchanged for 2 consecutive steps
|
||||
self.isonground -- true if in collision with negative Y
|
||||
self.isinliquid -- true if the node at foot level is drawtype=='liquid'
|
||||
|
||||
------------
|
||||
|
@ -318,6 +324,13 @@ function mobkit.is_there_yet2d(pos,dir,dest) -- obj positon; facing vector; dest
|
|||
function mobkit.isnear3d(p1,p2,thresh)
|
||||
-- returns true if pos p2 is within a cube with center at pos p1 and radius thresh
|
||||
|
||||
function mobkit.get_box_intersect_cols(pos,box)
|
||||
-- returns an array of {x=,z=} columns that the box intersects with.
|
||||
|
||||
function mobkit.get_box_displace_cols(pos,box,vec,dist)
|
||||
-- returns an array of {x=,z=} columns that the box would pass by if moved by horizontal vector vec
|
||||
-- if dist provided, vec gets normalized.
|
||||
|
||||
function mobkit.dir_to_rot(v,rot)
|
||||
-- converts a 3d vector v to rotation like in set_rotation() object method
|
||||
-- rot (optional) is current object rotation
|
||||
|
|
|
@ -1,25 +1,4 @@
|
|||
## Generic ignorable patterns and files
|
||||
*.obj
|
||||
*.blend1
|
||||
user.conf
|
||||
|
||||
globals = {
|
||||
"minetest",
|
||||
"mobkit",
|
||||
"stairs",
|
||||
"bucket",
|
||||
"armors",
|
||||
"bonemeal"
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
string = {fields = {"split"}},
|
||||
table = {fields = {"copy", "getn"}},
|
||||
|
||||
-- Builtin
|
||||
"vector", "ItemStack",
|
||||
"dump", "DIR_DELIM", "VoxelArea", "Settings",
|
||||
|
||||
-- MTG
|
||||
"default", "sfinv", "creative",
|
||||
}
|
||||
user.conf
|
|
@ -13,8 +13,9 @@ globals = {
|
|||
"hunger_ng",
|
||||
"dye",
|
||||
"armor",
|
||||
"player_physics",
|
||||
"player_monoids"
|
||||
"playerphysics",
|
||||
"player_monoids",
|
||||
"awards"
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
name = bale
|
||||
description = A bale of hay (wheat)
|
||||
depends = farming
|
||||
optional_depends =
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function mokapi.cron_clear(cron_time, modname)
|
||||
if cron_time > 0 then
|
||||
minetest.after(cron_time, function(cron_time, modname)
|
||||
minetest.after(cron_time, function()
|
||||
mokapi.cron_clear_mobs(cron_time, modname)
|
||||
end, cron_time, modname)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
name = mokapi
|
||||
description = A high level API for mobkit
|
||||
depends = mobkit
|
||||
optional_depends =
|
||||
version =
|
||||
|
|
|
@ -39,3 +39,6 @@ assert(loadfile(modpath .. "/api/api_bottled.lua"))(modpath, S)
|
|||
assert(loadfile(modpath .. "/api/api_colors.lua"))()
|
||||
assert(loadfile(modpath .. "/api/api_sell_buy.lua"))(S)
|
||||
assert(loadfile(modpath .. "/api/api_lifetime.lua"))()
|
||||
assert(loadfile(modpath .. "/api/api_back_home.lua"))()
|
||||
assert(loadfile(modpath .. "/api/api_on_deactivate.lua"))()
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
function petz.back_home(self)
|
||||
local pos = self.object:get_pos()
|
||||
local home_pos = self.home_pos
|
||||
if not home_pos then
|
||||
return
|
||||
end
|
||||
local distance = vector.distance(pos, home_pos)
|
||||
if distance <= petz.settings["back_home_distance"] then
|
||||
return
|
||||
end
|
||||
local node = minetest.get_node_or_nil(home_pos)
|
||||
local map_loaded
|
||||
if not node then
|
||||
-- Load the map at pos and try again
|
||||
--minetest.chat_send_all("manip")
|
||||
minetest.get_voxel_manip():read_from_map(home_pos, home_pos)
|
||||
node = minetest.get_node(pos)
|
||||
map_loaded = true
|
||||
end
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if node.name == "air" then
|
||||
--minetest.chat_send_all("test")
|
||||
local forceload
|
||||
if map_loaded then
|
||||
forceload = minetest.forceload_block(home_pos)
|
||||
--minetest.chat_send_all("FORCELOAD")
|
||||
if not forceload then
|
||||
--minetest.chat_send_all("NO FORCELOAD")
|
||||
return
|
||||
end
|
||||
end
|
||||
--minetest.chat_send_all("test2")
|
||||
self.object:set_pos(home_pos)
|
||||
if map_loaded then
|
||||
minetest.forceload_free_block(pos)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,9 +6,8 @@ local S = ...
|
|||
|
||||
petz.create_pet = function(placer, itemstack, pet_name, pos)
|
||||
local meta = itemstack:get_meta()
|
||||
local meta_table = meta:to_table()
|
||||
local sdata = minetest.serialize(meta_table)
|
||||
local mob = minetest.add_entity(pos, pet_name, sdata)
|
||||
local staticdata = meta:get_string("staticdata")
|
||||
local mob = minetest.add_entity(pos, pet_name, staticdata)
|
||||
local self = mob:get_luaentity()
|
||||
if self.is_wild == false and not(self.owner) then --not monster and not owner
|
||||
mokapi.set_owner(self, placer:get_player_name()) --set owner
|
||||
|
@ -79,32 +78,18 @@ petz.check_capture_items = function(self, wielded_item_name, clicker, check_inv_
|
|||
end
|
||||
|
||||
petz.capture = function(self, clicker, put_in_inventory)
|
||||
|
||||
self.captured = mobkit.remember(self, "captured", true) --IMPORTANT! mark as captured
|
||||
|
||||
local new_stack = ItemStack(self.name .. "_set") -- add special mob egg with all mob information
|
||||
|
||||
--Save the staticdata into the ItemStack-->
|
||||
local stack_meta = new_stack:get_meta()
|
||||
--local sett ="---TABLE---: "
|
||||
--local sett = ""
|
||||
--local i = 0
|
||||
for key, value in pairs(self) do
|
||||
local what_type = type(value)
|
||||
if what_type ~= "function" and what_type ~= "nil" and what_type ~= "userdata" then
|
||||
if what_type == "boolean" or what_type == "number" then
|
||||
value = tostring(value)
|
||||
elseif what_type == "table" then
|
||||
if key == "saddlebag_inventory" or key == "genes" or key == "father_genes" or key == "father_veloc_stats" then --only this tables to save serialized
|
||||
value = minetest.serialize(value)
|
||||
--minetest.chat_send_player("singleplayer", value)
|
||||
end
|
||||
end
|
||||
stack_meta:set_string(key, value)
|
||||
--i = i + 1
|
||||
--sett= sett .. ", ".. tostring(key).." : ".. tostring(self[key])
|
||||
end
|
||||
end
|
||||
--minetest.chat_send_player("singleplayer", sett)
|
||||
--minetest.chat_send_player("singleplayer", "status="..tostring(self.status))
|
||||
stack_meta:set_string("captured", "true") --IMPORTANT! mark as captured
|
||||
--minetest.chat_send_player("singleplayer", tostring(i))
|
||||
--Info text stuff:
|
||||
local ent = self.object:get_luaentity()
|
||||
local staticdata = ent:get_staticdata(self)
|
||||
stack_meta:set_string("staticdata", staticdata)
|
||||
|
||||
--Info text stuff for the ItemStack
|
||||
local info_text = ""
|
||||
if not(petz.str_is_empty(self.tag)) then
|
||||
info_text = info_text.."\n"..S("Name")..": "..self.tag
|
||||
|
|
|
@ -50,7 +50,7 @@ petz.drop_dreamcatcher = function(self)
|
|||
end
|
||||
|
||||
petz.dreamcatcher_save_metadata = function(self)
|
||||
if self.tag == "" or not(self.owner) then
|
||||
if not(self.dreamcatcher) or self.tag == "" or not(self.owner) then
|
||||
return
|
||||
end
|
||||
local item_list_table = petz.tamed_by_owner[self.owner]
|
||||
|
|
|
@ -1,23 +1,33 @@
|
|||
local S = ...
|
||||
|
||||
petz.create_form = function(player_name, context)
|
||||
local _context = {}
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
_context[player:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
local function create_context(player_name, tab_id)
|
||||
_context[player_name] = {}
|
||||
_context[player_name].tab_id = tab_id
|
||||
end
|
||||
|
||||
petz.create_form = function(player_name, buy)
|
||||
local pet = petz.pet[player_name]
|
||||
local form_size = {w = 4, h = 3}
|
||||
local buttonexit_pos = {x = 1, y = 6}
|
||||
local hungrystuff_pos = {x= 0, y = 0}
|
||||
local form_title = ""
|
||||
local tamagochi_form_stuff = ''
|
||||
local hungrystuff_pos
|
||||
local form_title
|
||||
local tamagochi_form_stuff
|
||||
local affinity_stuff = ''
|
||||
local form_orders = ''
|
||||
local more_form_orders = ''
|
||||
local tab_form = ''
|
||||
local final_form = ''
|
||||
if not context then
|
||||
context = {}
|
||||
context.tab_id = 1
|
||||
if not _context[player_name] then
|
||||
create_context(player_name, 1)
|
||||
end
|
||||
local tab_id = _context[player_name].tab_id
|
||||
local pet_icon = "petz_spawnegg_"..pet.type..".png"
|
||||
if context.tab_id == 1 and not(context.buy) then
|
||||
if tab_id == 1 and not(buy) then
|
||||
local pet_image_icon = "image[0.375,0.375;1,1;"..pet_icon.."]"
|
||||
if pet.affinity == nil then
|
||||
pet.affinity = 0
|
||||
|
@ -41,8 +51,8 @@ petz.create_form = function(player_name, context)
|
|||
"label[1.375,3;".. form_title .."]"..
|
||||
"image_button[".. (hungrystuff_pos.x+0.5) ..",".. (hungrystuff_pos.y +0.5)..";1,1;petz_pet_bowl_inv.png;btn_bowl;]"..
|
||||
affinity_stuff
|
||||
local hungry_label = ""
|
||||
local health_label = S("Health").." = "..tostring(pet.hp)
|
||||
local hungry_label
|
||||
if pet.fed == false then
|
||||
hungry_label = S("Hungry")
|
||||
else
|
||||
|
@ -72,15 +82,15 @@ petz.create_form = function(player_name, context)
|
|||
"checkbox[3.5,1.75;btn_muted;"..S("Muted")..";"..petz.vartostring(pet.muted).."]"..
|
||||
"checkbox[3.5,2.25;btn_show_tag;"..S("Show tag")..";"..petz.vartostring(pet.show_tag).."]"
|
||||
end
|
||||
local gender
|
||||
if pet.is_male == true then
|
||||
gender = S("Male")
|
||||
else
|
||||
gender = S("Female")
|
||||
end
|
||||
tamagochi_form_stuff = tamagochi_form_stuff..
|
||||
"label[3,0.875;"..gender.."]"
|
||||
if pet.breed == true then --Show the Gender
|
||||
local gender = ''
|
||||
if pet.is_male == true then
|
||||
gender = S("Male")
|
||||
else
|
||||
gender = S("Female")
|
||||
end
|
||||
tamagochi_form_stuff = tamagochi_form_stuff..
|
||||
"label[3,0.875;"..gender.."]"
|
||||
local pregnant_icon_x
|
||||
local pregnant_icon_y
|
||||
local pregnant_text_x
|
||||
|
@ -109,7 +119,7 @@ petz.create_form = function(player_name, context)
|
|||
"label["..(pregnant_text_x+0.375)..","..(pregnant_text_y+1)..";"..S("Pregnant").." ("..tostring(pregnant_remain_time).."s)]"
|
||||
elseif pet.is_male == false and pet.pregnant_count and pet.pregnant_count <= 0 then
|
||||
tamagochi_form_stuff = tamagochi_form_stuff..
|
||||
"label["..(pregnant_icon_x+0.5)..","..(infertile_text_y+1)..";"..S("Infertile").."]"
|
||||
"label["..(infertile_text_x+0.5)..","..(infertile_text_y+1)..";"..S("Infertile").."]"
|
||||
end
|
||||
if pet.is_baby == true then
|
||||
local growth_remain_time = petz.round(petz.settings.growth_time - pet.growth_time)
|
||||
|
@ -159,7 +169,7 @@ petz.create_form = function(player_name, context)
|
|||
form_orders = form_orders .. "button_exit[3.375,5.5;2,1;btn_guard;"..S("Guard").."]"
|
||||
end
|
||||
tab_form = tamagochi_form_stuff.. form_orders
|
||||
elseif context.tab_id == 1 and context.buy then
|
||||
elseif tab_id == 1 and buy then
|
||||
form_size.w = form_size.w + 1
|
||||
form_size.h = form_size.h + 2
|
||||
buttonexit_pos.x = buttonexit_pos.x + 1
|
||||
|
@ -175,7 +185,7 @@ petz.create_form = function(player_name, context)
|
|||
"label[2,2.5;"..tostring(item_amount).."]"..
|
||||
"style_type[button_exit;bgcolor=#333600;textcolor=white]"..
|
||||
"button_exit[2,3.25;2,1;btn_buy;"..S("Buy").."]"
|
||||
elseif context.tab_id == 2 and not(context.buy) then
|
||||
elseif tab_id == 2 and not(buy) then
|
||||
form_size.w = form_size.w + 1
|
||||
form_size.h = form_size.h + 2
|
||||
buttonexit_pos.y = buttonexit_pos.y - 2
|
||||
|
@ -188,7 +198,20 @@ petz.create_form = function(player_name, context)
|
|||
tab_form = tab_form .. "image[2,0.375;1,1;petz_lifetime.png]" .. "label[3,0.75;"..S("Lifetime").."]".."label[3,1;"..tostring(pet.lifetime).."]"
|
||||
end
|
||||
end
|
||||
elseif context.tab_id == 3 and petz.settings.selling and not(context.buy) then
|
||||
elseif (tab_id == 3 and not(buy) and pet.dreamcatcher) then
|
||||
form_size.w = form_size.w + 2
|
||||
form_size.h = form_size.h + 1
|
||||
buttonexit_pos.y = buttonexit_pos.y - 3
|
||||
tab_form = tab_form ..
|
||||
"checkbox[0.25,1.5;btn_back_home;"..S("Automatic Go back home")..";"..petz.vartostring(pet.back_home).."]"..
|
||||
"label[1.3,0.75;<< "..S("Click to set the home").."]"..
|
||||
"image_button_exit[0.25,0.25;1,1;petz_kennel.png;btn_set_home;"..S("Set").."\n"..S("Home").."]"
|
||||
if pet.home_pos then
|
||||
tab_form = tab_form ..
|
||||
"label[0.25,2.0;"..S("Home Pos")..": x="..tostring(petz.truncate(pet.home_pos.x,1))
|
||||
..", y="..petz.truncate(pet.home_pos.y,1)..", z="..petz.truncate(pet.home_pos.z,1).."]"
|
||||
end
|
||||
elseif (tab_id ==3 or tab_id ==4) and petz.settings.selling and not(buy) then
|
||||
form_size.w = form_size.w + 1
|
||||
form_size.h = form_size.h + 2
|
||||
buttonexit_pos.y = buttonexit_pos.y - 2
|
||||
|
@ -219,20 +242,24 @@ petz.create_form = function(player_name, context)
|
|||
local tab_main = S("Main")
|
||||
local tab_other = S("Other")
|
||||
local tab_shop = S("Shop")
|
||||
local tab_home = S("Home")
|
||||
local tab_header
|
||||
if context.buy then
|
||||
if buy then
|
||||
tab_header = tab_shop
|
||||
else
|
||||
tab_header =tab_main..","..tab_other
|
||||
tab_header = tab_main..","..tab_other
|
||||
if pet.dreamcatcher then
|
||||
tab_header = tab_header..","..tab_home
|
||||
end
|
||||
if not(minetest.is_singleplayer()) then
|
||||
tab_header = tab_header..","..tab_shop
|
||||
end
|
||||
end
|
||||
--minetest.chat_send_player("singleplayer", tab_header)
|
||||
final_form =
|
||||
local final_form =
|
||||
"size["..(form_size.w+0.875)..","..(form_size.h+1)..";]"..
|
||||
"real_coordinates[true]"..
|
||||
"tabheader[0,0;tabheader;"..tab_header..";"..tostring(context.tab_id)..";true;false]"..
|
||||
"tabheader[0,0;tabheader;"..tab_header..";"..tostring(tab_id)..";true;false]"..
|
||||
tab_form..
|
||||
"style_type[button_exit;bgcolor=#006699;textcolor=white]"..
|
||||
"button_exit["..(buttonexit_pos.x+0.5)..","..(buttonexit_pos.y+0.75)..";1,1;btn_close;"..S("Close").."]"
|
||||
|
@ -248,9 +275,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
if fields.tabheader then
|
||||
local tab_id = tonumber(fields.tabheader)
|
||||
if tab_id > 0 then
|
||||
local context = {}
|
||||
context.tab_id = tab_id
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, context))
|
||||
create_context(player_name, tab_id)
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, false))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -271,8 +297,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
mobkit.clear_queue_low(pet)
|
||||
mobkit.clear_queue_high(pet)
|
||||
pet.status = nil
|
||||
mobkit.hq_fly(pet, 0)
|
||||
minetest.after(2.5, function(pet)
|
||||
petz.hq_fly(pet, 0)
|
||||
minetest.after(2.5, function()
|
||||
if mobkit.is_alive(pet) then
|
||||
mobkit.clear_queue_low(pet)
|
||||
pet.object:set_acceleration({ x = 0, y = 0, z = 0 })
|
||||
|
@ -290,7 +316,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end
|
||||
pet.object:set_attach(player, "Arm_Left", shoulder_pos, {x=0, y=0, z=180})
|
||||
pet.object:set_properties({physical = false,})
|
||||
minetest.after(120.0, function(pet)
|
||||
minetest.after(120.0, function()
|
||||
if mobkit.is_alive(pet) then
|
||||
pet.object:set_detach()
|
||||
pet.object:set_properties({physical = true,})
|
||||
|
@ -339,6 +365,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
pet.exchange_item_amount = mobkit.remember(pet, "exchange_item_amount", mokapi.delimit_number( tonumber(fields.fld_exchange_item_amount), {min=1, max=99}) or 1)
|
||||
elseif fields.btn_buy then
|
||||
petz.buy(pet, player)
|
||||
elseif fields.btn_back_home then
|
||||
pet.back_home= mobkit.remember(pet, "back_home", minetest.is_yes(fields.btn_back_home))
|
||||
elseif fields.btn_set_home then
|
||||
pet.home_pos= mobkit.remember(pet, "home_pos", pet.object:get_pos())
|
||||
create_context(player_name, 3)
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, false))
|
||||
end
|
||||
if fields.ipt_name then
|
||||
pet.tag = minetest.formspec_escape(string.sub(fields.ipt_name, 1 , 12))
|
||||
|
@ -350,8 +382,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end
|
||||
end
|
||||
petz.update_nametag(pet)
|
||||
_context[player_name] = nil
|
||||
return true
|
||||
else
|
||||
_context[player_name] = nil
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
@ -419,14 +453,13 @@ petz.create_food_form = function(self)
|
|||
items_desc = items_desc .. ", "
|
||||
end
|
||||
end
|
||||
local formspec = ""
|
||||
local form_size = {w= 3, h= 3}
|
||||
local button_exit = {x= 1, y= 2}
|
||||
if self.breed == true then
|
||||
form_size.h = form_size.h + 1
|
||||
button_exit.y = button_exit.y + 1
|
||||
end
|
||||
formspec =
|
||||
local formspec =
|
||||
"size["..form_size.w..","..form_size.h.."]"..
|
||||
"image[0,0;1,1;petz_spawnegg_"..self.type..".png]"..
|
||||
"label[1,0;"..S("Food").."]"..
|
||||
|
@ -450,7 +483,6 @@ petz.create_food_form = function(self)
|
|||
end
|
||||
|
||||
petz.create_affinity_form = function(self)
|
||||
local formspec = ""
|
||||
local form_size = {w= 3, h= 4}
|
||||
local button_exit = {x= 1, y= 3}
|
||||
local feed_status, feed_status_color
|
||||
|
@ -469,7 +501,7 @@ petz.create_affinity_form = function(self)
|
|||
brushing_status = S("Not brushed")..": " .. tostring(petz.calculate_affinity_change(-petz.settings.tamagochi_brush_rate))
|
||||
brushing_status_color = petz.colors["red"]
|
||||
end
|
||||
formspec =
|
||||
local formspec =
|
||||
"size["..form_size.w..","..form_size.h.."]"..
|
||||
"image[0,0;1,1;petz_affinity_heart.png]"..
|
||||
"label[1,0;"..S("Affinity").."]"..
|
||||
|
@ -487,7 +519,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
local player_name = player:get_player_name()
|
||||
local pet = petz.pet[player_name]
|
||||
if pet and (mobkit.is_alive(pet)) then
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, context))
|
||||
create_context(player_name, 1)
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, false))
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
@ -517,9 +550,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
petz.abandon_pet(pet, msg)
|
||||
end
|
||||
else
|
||||
local context = {}
|
||||
context.tab_id = 2
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, context))
|
||||
create_context(player_name, 2)
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, false))
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
|
|
@ -6,11 +6,15 @@ petz.dyn_prop = {
|
|||
accel = {type= "int", default = 1},
|
||||
affinity = {type= "int", default = 100},
|
||||
anthill_founded = {type= "boolean", default = false},
|
||||
back_home = {type= "boolean", default = false},
|
||||
beaver_oil_applied = {type= "boolean", default = false},
|
||||
behive = {type= "pos", default = false},
|
||||
behive = {type= "pos", default = nil},
|
||||
brushed = {type= "boolean", default = false},
|
||||
captured = {type= "boolean", default = false},
|
||||
child = {type= "boolean", default = false},
|
||||
colorized = {type= "string", default = nil},
|
||||
convert = {type= "string", default = nil},
|
||||
convert_to = {type= "string", default = nil},
|
||||
convert_count = {type= "int", default = 5},
|
||||
dreamcatcher = {type= "boolean", default = false},
|
||||
dead = {type= "boolean", default = false},
|
||||
|
@ -31,9 +35,10 @@ petz.dyn_prop = {
|
|||
genes = {type= "table", default = {}},
|
||||
growth_time = {type= "int", default = 0},
|
||||
herding = {type= "boolean", default = false},
|
||||
home_pos = {type= "table", default = nil},
|
||||
horseshoes = {type= "int", default = 0},
|
||||
is_baby = {type= "boolean", default = false},
|
||||
is_male = {type= "boolean", default = false},
|
||||
is_male = {type= "boolean", default = nil},
|
||||
is_pregnant = {type= "boolean", default = false},
|
||||
is_rut = {type= "boolean", default = false},
|
||||
lashed = {type= "boolean", default = false},
|
||||
|
@ -48,14 +53,13 @@ petz.dyn_prop = {
|
|||
pregnant_time = {type= "int", default = 0},
|
||||
saddle = {type= "boolean", default = false},
|
||||
saddlebag = {type= "boolean", default = false},
|
||||
saddlebag_inventory = {type= "table", default = nil},
|
||||
set_vars = {type= "boolean", default = false},
|
||||
saddlebag_inventory = {type= "table", default = {}},
|
||||
shaved = {type= "boolean", default = false},
|
||||
show_tag = {type= "boolean", default = false},
|
||||
sleep_start_time = {type= "int", default = nil},
|
||||
sleep_end_time = {type= "int", default = nil},
|
||||
square_ball_attached = {type= "boolean", default = false},
|
||||
status = {type= "string", default = ""},
|
||||
status = {type= "string", default = nil},
|
||||
tag = {type= "string", default = ""},
|
||||
tamed = {type= "boolean", default = false},
|
||||
--texture_no = {type= "int", default = 1}, --do not use!!! OR MISSING TEXTURE
|
||||
|
@ -63,6 +67,29 @@ petz.dyn_prop = {
|
|||
was_killed_by_player = {type= "boolean", default = false},
|
||||
}
|
||||
|
||||
petz.compose_texture= function(self)
|
||||
local texture
|
||||
if self.type == "lamb" then
|
||||
local shaved_string = ""
|
||||
if self.shaved == true then
|
||||
shaved_string = "_shaved"
|
||||
end
|
||||
texture = "petz_lamb".. shaved_string .."_"..self.skin_colors[self.texture_no]..".png"
|
||||
elseif self.is_mountable == true then
|
||||
if self.saddle then
|
||||
texture = "petz_"..self.type.."_"..self.skin_colors[self.texture_no]..".png" .. "^petz_"..self.type.."_saddle.png"
|
||||
else
|
||||
texture = "petz_"..self.type.."_"..self.skin_colors[self.texture_no]..".png"
|
||||
end
|
||||
if self.saddlebag then
|
||||
texture = texture .. "^petz_"..self.type.."_saddlebag.png"
|
||||
end
|
||||
else
|
||||
texture = self.textures[self.texture_no]
|
||||
end
|
||||
return texture
|
||||
end
|
||||
|
||||
petz.cleanup_prop= function(self)
|
||||
self.warn_attack = false --reset the warn attack
|
||||
self.driver = nil --no driver
|
||||
|
@ -129,11 +156,19 @@ petz.load_vars = function(self)
|
|||
end
|
||||
|
||||
function petz.set_initial_properties(self, staticdata, dtime_s)
|
||||
--minetest.chat_send_all(staticdata)
|
||||
local static_data_table = minetest.deserialize(staticdata)
|
||||
local captured_mob = false
|
||||
local baby_born = false
|
||||
--minetest.chat_send_player("singleplayer", staticdata)
|
||||
if static_data_table and static_data_table["fields"] and static_data_table["fields"]["captured"] then
|
||||
--TO DELETE IN FUTURE VERSIONS-->
|
||||
local static_table_name
|
||||
if static_data_table and static_data_table["memory"] then
|
||||
static_table_name = "memory"
|
||||
else
|
||||
static_table_name = "fields"
|
||||
end
|
||||
--<
|
||||
if static_data_table and static_data_table[static_table_name] and static_data_table[static_table_name]["captured"] then
|
||||
captured_mob = true
|
||||
elseif static_data_table and static_data_table["baby_born"] and static_data_table["baby_born"] == true then
|
||||
baby_born = true
|
||||
|
@ -143,56 +178,29 @@ function petz.set_initial_properties(self, staticdata, dtime_s)
|
|||
--
|
||||
--dtime_s == 0 differenciates between loaded and new created mobs
|
||||
if dtime_s == 0 and captured_mob == false then --set some vars
|
||||
--Mob Specific
|
||||
--Lamb
|
||||
if self.type == "lamb" then --set a random color
|
||||
self.food_count_wool = mobkit.remember(self, "food_count_wool", 0)
|
||||
self.shaved = mobkit.remember(self, "shaved", false)
|
||||
elseif self.type == "puppy" then
|
||||
self.square_ball_attached = mobkit.remember(self, "square_ball_attached", false)
|
||||
elseif self.is_mountable == true then
|
||||
--Load default settings ->
|
||||
for key, value in pairs(petz.dyn_prop) do
|
||||
self[key] = value["default"]
|
||||
end
|
||||
--Define some settings ->
|
||||
--Set a random gender for all the mobs (not defined in the entity definition)
|
||||
if self.is_male == nil then
|
||||
self.is_male = petz.set_random_gender() --set a random gender
|
||||
end
|
||||
mobkit.remember(self, "is_male", self.is_male)
|
||||
if self.is_mountable == true then
|
||||
if baby_born == false then
|
||||
self.max_speed_forward= mobkit.remember(self, "max_speed_forward", math.random(2, 4)) --set a random velocity for walk and run
|
||||
self.max_speed_reverse= mobkit.remember(self, "max_speed_reverse", math.random(1, 2))
|
||||
self.accel= mobkit.remember(self, "accel", math.random(2, 4))
|
||||
end
|
||||
self.driver = mobkit.remember(self, "driver", nil)
|
||||
--Saddlebag
|
||||
self.saddle = mobkit.remember(self, "saddle", false)
|
||||
if self.has_saddlebag == true then
|
||||
self.saddlebag_ref = nil
|
||||
self.saddlebag_inventory = mobkit.remember(self, "saddlebag_inventory", {})
|
||||
end
|
||||
self.gallop = mobkit.remember(self, "gallop", false)
|
||||
self.gallop_time = mobkit.remember(self, "gallop_time", 0)
|
||||
self.gallop_exhausted = mobkit.remember(self, "gallop_exhausted", false)
|
||||
self.gallop_recover_time = mobkit.remember(self, "gallop_recover_time", petz.settings.gallop_recover_time)
|
||||
end
|
||||
if self.parents then
|
||||
if self.parents then --for chicken only
|
||||
self.is_baby = mobkit.remember(self, "is_baby", true)
|
||||
end
|
||||
if self.type == "pony" then --not in the previopus loop, cos also is mountable
|
||||
self.horseshoes = mobkit.remember(self, "horseshoes", 0)
|
||||
end
|
||||
if self.herd then
|
||||
self.herding = mobkit.remember(self, "herding", false)
|
||||
end
|
||||
--Mobs that can have babies
|
||||
if self.breed == true then
|
||||
if self.is_male == nil then
|
||||
self.is_male = petz.set_random_gender() --set a random gender
|
||||
end
|
||||
mobkit.remember(self, "is_male", self.is_male)
|
||||
self.is_rut = mobkit.remember(self, "is_rut", false)
|
||||
self.is_pregnant = mobkit.remember(self, "is_pregnant", false)
|
||||
self.pregnant_time = mobkit.remember(self, "pregnant_time", 0.0)
|
||||
self.father_genes = mobkit.remember(self, "father_genes", {})
|
||||
self.father_veloc_stats = mobkit.remember(self, "father_veloc_stats", {})
|
||||
self.pregnant_count = mobkit.remember(self, "pregnant_count", petz.settings.pregnant_count)
|
||||
self.is_baby = mobkit.remember(self, "is_baby", false)
|
||||
self.growth_time = mobkit.remember(self, "growth_time", 0.0)
|
||||
--Genetics
|
||||
self.genes = {}
|
||||
local genes_mutation = false
|
||||
if self.mutation and (self.mutation > 0) and math.random(1, 200) == 1 then
|
||||
genes_mutation = true
|
||||
|
@ -230,9 +238,6 @@ function petz.set_initial_properties(self, staticdata, dtime_s)
|
|||
end
|
||||
mobkit.remember(self, "genes", self.genes)
|
||||
end
|
||||
if self.lay_eggs == true then
|
||||
self.eggs_count = mobkit.remember(self, "eggs_count", 0)
|
||||
end
|
||||
--ALL the mobs
|
||||
--Get a texture
|
||||
if not(self.texture_no) then
|
||||
|
@ -248,38 +253,12 @@ function petz.set_initial_properties(self, staticdata, dtime_s)
|
|||
self.texture_no = 1
|
||||
end
|
||||
end
|
||||
self.set_vars = mobkit.remember(self, "set_vars", true)
|
||||
self.tag = mobkit.remember(self, "tag", "")
|
||||
self.show_tag = mobkit.remember(self, "show_tag", false)
|
||||
self.tamed = mobkit.remember(self, "tamed", false)
|
||||
self.owner = mobkit.remember(self, "owner", nil)
|
||||
self.fed = mobkit.remember(self, "fed", true)
|
||||
self.for_sale = mobkit.remember(self, "for_sale", false)
|
||||
self.exchange_item_index = mobkit.remember(self, "exchange_item_index", 1)
|
||||
self.exchange_item_amount = mobkit.remember(self, "exchange_item_amount", 1)
|
||||
self.brushed = mobkit.remember(self, "brushed", false)
|
||||
self.food_count = mobkit.remember(self, "food_count", 0)
|
||||
self.lifetime = mobkit.remember(self, "lifetime", nil)
|
||||
self.was_killed_by_player = mobkit.remember(self, "was_killed_by_player", false)
|
||||
self.dreamcatcher = mobkit.remember(self, "dreamcatcher", false)
|
||||
self.status = mobkit.remember(self, "status", nil)
|
||||
self.warn_attack = mobkit.remember(self, "warn_attack", false)
|
||||
self.colorized = mobkit.remember(self, "colorized", nil)
|
||||
self.convert = mobkit.remember(self, "convert", nil)
|
||||
self.muted = mobkit.remember(self, "muted", false)
|
||||
if petz.settings[self.type.."_convert_count"] then
|
||||
self.convert_count = mobkit.remember(self, "convert_count", petz.settings[self.type.."_convert_count"])
|
||||
end
|
||||
if self.init_tamagochi_timer== true then
|
||||
petz.init_tamagochi_timer(self)
|
||||
end
|
||||
if self.has_affinity == true then
|
||||
self.affinity = mobkit.remember(self, "affinity", 100)
|
||||
end
|
||||
if self.is_wild == true then
|
||||
self.lashed = mobkit.remember(self, "lashed", false)
|
||||
self.lashing_count = mobkit.remember(self, "lashing_count", 0)
|
||||
end
|
||||
petz.calculate_sleep_times(self) --Sleep behaviour
|
||||
--
|
||||
--2. ALREADY EXISTING MOBS
|
||||
|
@ -290,58 +269,38 @@ function petz.set_initial_properties(self, staticdata, dtime_s)
|
|||
--3. CAPTURED MOBS
|
||||
--
|
||||
else
|
||||
self.captured = mobkit.remember(self, "captured", false) --IMPORTANT! mark as not captured
|
||||
for key, value in pairs(petz.dyn_prop) do
|
||||
local prop_value
|
||||
if value["type"] == "string" then
|
||||
prop_value = static_data_table["fields"][key]
|
||||
prop_value = static_data_table[static_table_name][key]
|
||||
elseif value["type"] == "int" then
|
||||
prop_value = tonumber(static_data_table["fields"][key])
|
||||
prop_value = tonumber(static_data_table[static_table_name][key])
|
||||
elseif value["type"] == "boolean" then
|
||||
prop_value = minetest.is_yes(static_data_table["fields"][key])
|
||||
prop_value = minetest.is_yes(static_data_table[static_table_name][key])
|
||||
elseif value["type"] == "table" then
|
||||
prop_value = minetest.deserialize(static_data_table["fields"][key])
|
||||
prop_value = minetest.deserialize(static_data_table[static_table_name][key])
|
||||
elseif value["type"] == "player" then
|
||||
prop_value = nil
|
||||
end
|
||||
self[key] = mobkit.remember(self, key, prop_value) or value["default"]
|
||||
end
|
||||
self.texture_no = tonumber(static_data_table["fields"]["texture_no"])
|
||||
end
|
||||
|
||||
--Custom textures
|
||||
if captured_mob == true or self.breed == true then
|
||||
local texture
|
||||
--Mob Specific
|
||||
--Lamb
|
||||
if self.type == "lamb" then
|
||||
local shaved_string = ""
|
||||
if self.shaved == true then
|
||||
shaved_string = "_shaved"
|
||||
end
|
||||
texture = "petz_lamb".. shaved_string .."_"..self.skin_colors[self.texture_no]..".png"
|
||||
elseif self.is_mountable == true then
|
||||
if self.saddle then
|
||||
texture = "petz_"..self.type.."_"..self.skin_colors[self.texture_no]..".png" .. "^petz_"..self.type.."_saddle.png"
|
||||
else
|
||||
texture = "petz_"..self.type.."_"..self.skin_colors[self.texture_no]..".png"
|
||||
end
|
||||
if self.saddlebag then
|
||||
texture = texture .. "^petz_"..self.type.."_saddlebag.png"
|
||||
end
|
||||
else
|
||||
texture = self.textures[self.texture_no]
|
||||
end
|
||||
local texture= petz.compose_texture(self) --compose the texture
|
||||
mobkit.remember(self, "texture_no", self.texture_no)
|
||||
petz.set_properties(self, {textures = {texture}})
|
||||
end
|
||||
if self.type == "bee" and self.queen then --delay to create beehive
|
||||
minetest.after(math.random(120, 150), function(self)
|
||||
minetest.after(math.random(120, 150), function()
|
||||
if mobkit.is_alive(self.object) then
|
||||
self.create_beehive = mobkit.remember(self, "create_beehive", true)
|
||||
end
|
||||
end, self)
|
||||
elseif self.type == "ant" and self.ant_type == "queen" then
|
||||
minetest.after(math.random(120, 150), function(self)
|
||||
minetest.after(math.random(120, 150), function()
|
||||
if mobkit.is_alive(self.object) then
|
||||
self.create_anthill = mobkit.remember(self, "create_anthill", true)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
function petz.on_deactivate(self)
|
||||
petz.dreamcatcher_save_metadata(self)
|
||||
end
|
|
@ -71,7 +71,7 @@ function petz.on_punch(self, puncher, time_from_last_punch, tool_capabilities, d
|
|||
self.object:set_properties(self, {textures = {punch_texture}})
|
||||
minetest.after(0.1, function()
|
||||
if self then
|
||||
self.object:set_properties(self, {textures = { self.textures[self.texture_no]}})
|
||||
self.object:set_properties(self, {textures = { petz.compose_texture(self) }})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ petz.on_rightclick = function(self, clicker)
|
|||
local wielded_item = clicker:get_wielded_item()
|
||||
local wielded_item_name = wielded_item:get_name()
|
||||
local show_form = false
|
||||
local context = {}
|
||||
local buy
|
||||
|
||||
if ((self.is_pet == true) and is_owner and (self.can_be_brushed == true)) -- If brushing or spread beaver oil
|
||||
and ((wielded_item_name == "petz:hairbrush") or (wielded_item_name == "petz:beaver_oil")) then
|
||||
|
@ -62,7 +62,7 @@ petz.on_rightclick = function(self, clicker)
|
|||
petz.capture(self, clicker, true)
|
||||
minetest.chat_send_player("singleplayer", S("Your").." "..S(pet_name).." "..S("has been captured")..".")
|
||||
elseif self.breed and wielded_item_name == petz.settings[self.type.."_breed"] and not(self.is_baby) then
|
||||
minetest.chat_send_all("test="..petz.settings[self.type.."_breed"])
|
||||
--minetest.chat_send_all("test="..petz.settings[self.type.."_breed"])
|
||||
petz.breed(self, clicker, wielded_item, wielded_item_name)
|
||||
elseif (wielded_item_name == "petz:dreamcatcher") and (self.tamed == true) and (self.is_pet == true) and is_owner then
|
||||
petz.put_dreamcatcher(self, clicker, wielded_item, wielded_item_name)
|
||||
|
@ -107,17 +107,16 @@ petz.on_rightclick = function(self, clicker)
|
|||
show_form = true
|
||||
end
|
||||
elseif petz.settings.selling and not(minetest.is_singleplayer()) and self.for_sale and self.owner and not(self.owner == player_name) then --Buy Form
|
||||
context.buy = true
|
||||
buy = true
|
||||
show_form = true
|
||||
else --Else open the Form
|
||||
if (self.is_pet == true) and ((self.tamed == true) and (self.owner == player_name)) then
|
||||
context.buy = false
|
||||
buy = false
|
||||
show_form = true
|
||||
end
|
||||
end
|
||||
if show_form then
|
||||
context.tab_id = 1
|
||||
petz.pet[player_name]= self
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, context))
|
||||
minetest.show_formspec(player_name, "petz:form_orders", petz.create_form(player_name, buy))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,13 +12,16 @@ petz.on_step = function(self, dtime)
|
|||
if self.gallop == true then
|
||||
petz.gallop(self, on_step_time)
|
||||
end
|
||||
if self.dreamcatcher then
|
||||
if not(self.on_deactivate) then
|
||||
petz.dreamcatcher_save_metadata(self)
|
||||
end
|
||||
local lifetime = petz.check_lifetime(self)
|
||||
if lifetime then
|
||||
petz.lifetime_timer(self, lifetime, on_step_time)
|
||||
end
|
||||
if self.dreamcatcher and self.back_home then
|
||||
petz.back_home(self)
|
||||
end
|
||||
--Tamagochi
|
||||
--Check the hungry
|
||||
if petz.settings.tamagochi_mode == true and self.owner and self.is_pet and petz.settings.tamagochi_hungry_warning > 0 and not(self.status=="sleep") and petz.settings[self.type.."_follow"] then
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
petz.ownthing = function(self)
|
||||
self.status = mobkit.remember(self, "status", nil)
|
||||
if self.can_fly then
|
||||
mobkit.hq_wanderfly(self, 0)
|
||||
petz.hq_wanderfly(self, 0)
|
||||
elseif self.can_swin and self.isinliquid then
|
||||
mobkit.hq_aqua_roam(self, 0, self.max_speed)
|
||||
else
|
||||
|
@ -20,7 +20,7 @@ petz.standhere = function(self)
|
|||
mobkit.clear_queue_high(self)
|
||||
mobkit.clear_queue_low(self)
|
||||
if self.can_fly == true then
|
||||
if mobkit.node_name_in(self, "below") == "air" then
|
||||
if petz.node_name_in(self, "below") == "air" then
|
||||
mobkit.animate(self, "fly")
|
||||
else
|
||||
mobkit.animate(self, "stand")
|
||||
|
@ -51,10 +51,10 @@ petz.follow = function(self, player)
|
|||
self.status = mobkit.remember(self, "status", "follow")
|
||||
if self.can_fly then
|
||||
mobkit.animate(self, "fly")
|
||||
mobkit.hq_followliquidair(self, 100, player)
|
||||
petz.hq_followliquidair(self, 100, player)
|
||||
elseif self.can_swin and self.isinliquid then
|
||||
mobkit.animate(self, "def")
|
||||
mobkit.hq_followliquidair(self, 100, player)
|
||||
petz.hq_followliquidair(self, 100, player)
|
||||
else
|
||||
mobkit.hq_follow(self, 100, player)
|
||||
end
|
||||
|
@ -63,8 +63,8 @@ end
|
|||
petz.alight = function(self)
|
||||
mobkit.clear_queue_low(self)
|
||||
mobkit.clear_queue_high(self)
|
||||
if not(mobkit.node_name_in(self, "below") == "air") then
|
||||
if not(petz.node_name_in(self, "below") == "air") then
|
||||
mobkit.animate(self, "fly")
|
||||
end
|
||||
mobkit.hq_alight(self, 0)
|
||||
petz.hq_alight(self, 0)
|
||||
end
|
||||
|
|
|
@ -6,8 +6,8 @@ petz.poop = function(self, pos)
|
|||
if not(petz.settings.poop) or not(self.tamed) or not(self.poop) or self.child == true or petz.is_jumping(self) or not(petz.is_standing(self)) or math.random(1, petz.settings.poop_rate) > 1 then
|
||||
return
|
||||
end
|
||||
local node_name_below = mobkit.node_name_in(self, "below")
|
||||
local node_name = mobkit.node_name_in(self, "self")
|
||||
local node_name_below = petz.node_name_in(self, "below")
|
||||
local node_name = petz.node_name_in(self, "self")
|
||||
--minetest.chat_send_player("singleplayer", node_name)
|
||||
if node_name == "air" and node_name_below ~= "air" then
|
||||
pos.y = pos.y - 0.75
|
||||
|
|
|
@ -162,7 +162,7 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
petz.init_convert_to_chrysalis = function(self)
|
||||
minetest.after(math.random(1200, 1500), function(self)
|
||||
minetest.after(math.random(1200, 1500), function()
|
||||
if not(mobkit.is_alive(self)) then
|
||||
return
|
||||
end
|
||||
|
@ -176,7 +176,7 @@ petz.init_convert_to_chrysalis = function(self)
|
|||
end
|
||||
|
||||
petz.init_lay_eggs = function(self)
|
||||
minetest.after(math.random(150, 240), function(self)
|
||||
minetest.after(math.random(150, 240), function()
|
||||
if not(mobkit.is_alive(self)) then
|
||||
return
|
||||
end
|
||||
|
@ -184,7 +184,7 @@ petz.init_lay_eggs = function(self)
|
|||
return
|
||||
end
|
||||
petz.alight(self)
|
||||
minetest.after(10.0, function(self)
|
||||
minetest.after(10.0, function()
|
||||
if not(mobkit.is_alive(self)) then
|
||||
return
|
||||
end
|
||||
|
@ -192,7 +192,7 @@ petz.init_lay_eggs = function(self)
|
|||
if minetest.get_node(pos) and minetest.get_node(pos).name ~= "air" then
|
||||
return
|
||||
end
|
||||
local node_name = mobkit.node_name_in(self, "below")
|
||||
local node_name = petz.node_name_in(self, "below")
|
||||
local spawn_egg = false
|
||||
if string.sub(petz.settings.silkworm_lay_egg_on_node, 1, 5) == "group" then
|
||||
local node_group = minetest.get_item_group(node_name, string.sub(petz.settings.silkworm_lay_egg_on_node, 7))
|
||||
|
|
|
@ -65,12 +65,12 @@ petz.sleep = function(self, prty, force)
|
|||
mobkit.animate(self, 'sleep')
|
||||
local texture = self.textures[self.texture_no]
|
||||
self.object:set_properties(self, {textures = {texture.."^petz_"..self.type.."_sleep.png"}}) --sleeping eyes
|
||||
mobkit.hq_sleep(self, prty, force)
|
||||
petz.hq_sleep(self, prty, force)
|
||||
end
|
||||
|
||||
function mobkit.hq_sleep(self, prty, force)
|
||||
function petz.hq_sleep(self, prty, force)
|
||||
local timer = 2
|
||||
local func=function(self)
|
||||
local func=function()
|
||||
timer = timer - self.dtime
|
||||
if timer < 0 then
|
||||
if not(force) then
|
||||
|
|
|
@ -187,15 +187,17 @@ petz.spawn_mob = function(spawn_pos, limit_max_mobs, abr, liquidflag)
|
|||
else
|
||||
spawn_pos.z = spawn_pos.z - 2
|
||||
end
|
||||
--[[
|
||||
if i > 1 then
|
||||
local height, liquidflag = mobkit.get_terrain_height(spawn_pos, 32)
|
||||
if height or (liquidflag and ent.can_swin) then
|
||||
local node = petz.get_node_below(spawn_pos)
|
||||
if not(mokapi.item_in_itemlist(node.name, petz.settings[random_mob.."_spawn_nodes"])) then
|
||||
local height, liquidflag2 = mobkit.get_terrain_height(spawn_pos, 32)
|
||||
if height or (liquidflag2 and ent.can_swin) then
|
||||
local node_below = petz.get_node_below(spawn_pos)
|
||||
if not(mokapi.item_in_itemlist(node_below.name, petz.settings[random_mob.."_spawn_nodes"])) then
|
||||
spawn = false
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
if spawn == true then
|
||||
spawn_pos = petz.pos_to_spawn(random_mob_name, spawn_pos) --recalculate pos.y for bigger mobs
|
||||
minetest.add_entity(spawn_pos, random_mob_name)
|
||||
|
@ -211,7 +213,7 @@ minetest.register_globalstep(function(dtime)
|
|||
local abr = tonumber(minetest.get_mapgen_setting('active_block_range')) or 3
|
||||
local radius = abr * 16 --recommended
|
||||
local interval = petz.settings.spawn_interval
|
||||
local spawn_pos, liquidflag, cave = mobkit.get_spawn_pos_abr(dtime, interval, radius, petz.settings.spawn_chance, 0.2)
|
||||
local spawn_pos, liquidflag = mobkit.get_spawn_pos_abr(dtime, interval, radius, petz.settings.spawn_chance, 0.2)
|
||||
if spawn_pos then
|
||||
petz.spawn_mob(spawn_pos, true, abr, liquidflag)
|
||||
end
|
||||
|
|
|
@ -42,7 +42,7 @@ end
|
|||
--
|
||||
|
||||
petz.timer = function(self)
|
||||
minetest.after(petz.settings.tamagochi_check_time, function(self)
|
||||
minetest.after(petz.settings.tamagochi_check_time, function()
|
||||
if mobkit.is_alive(self) then
|
||||
if (not(minetest.is_singleplayer())) and (petz.settings.tamagochi_check_if_player_online == true) then
|
||||
if minetest.player_exists(self.owner) == false then --if pet owner is not online
|
||||
|
|
|
@ -4,12 +4,12 @@ awards.register_trigger("milk", {
|
|||
auto_description = { "Do a foo", "Foo @1 times" },
|
||||
})
|
||||
|
||||
minetest.register_on_milk(function()
|
||||
for _, trigger in pairs(awards.on.milk) do
|
||||
--minetest.register_on_milk(function()
|
||||
--for _, trigger in pairs(awards.on.milk) do
|
||||
|
||||
|
||||
if condition then
|
||||
awards.unlock(trigger)
|
||||
end
|
||||
end
|
||||
end)
|
||||
--if condition then
|
||||
--awards.unlock(trigger)
|
||||
--end
|
||||
--end
|
||||
--end)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
local modname = "petz"
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
|
||||
-- internationalization boilerplate
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
|
|
@ -13,6 +13,7 @@ Anthill Entrance=Entrada do formigueiro
|
|||
Alight=Posse
|
||||
A silk bobbin has been created!=Uma bobina de seda foi criada!
|
||||
Amount=Quantidade
|
||||
Automatic Go back home=Regresso automático a casa
|
||||
Bat=Morcego
|
||||
Beaver Fur=Pele de castor
|
||||
Beaver Oil=Óleo de castor
|
||||
|
@ -34,6 +35,7 @@ Blueberry Muffin=Muffin de mirtilo
|
|||
Bone=Ossos
|
||||
Bottle with Moth=Garrafa com traça
|
||||
Brushed=Escovado
|
||||
Bunny=Coelhinho
|
||||
Butterfly=Borboleta
|
||||
Butterfly Showcase=Exibição de borboletas
|
||||
Buy=Compre
|
||||
|
@ -100,6 +102,8 @@ has starved to death!!!=morreu de fome!!!
|
|||
Saúde=Abraço
|
||||
Hen=Galinha
|
||||
Herding=Pastoreio
|
||||
Home=Casa
|
||||
Home Pos=Pos. de casa
|
||||
Honey=Mel
|
||||
Honeycomb=Favo de mel
|
||||
Honey Bottle=Pote de mel
|
||||
|
@ -161,16 +165,19 @@ Poop Block=Bloco de cocozinho
|
|||
Pregnant=Grávida
|
||||
Pumpkin Hood=Capuz de abóbora
|
||||
Puppy=Cachorro
|
||||
Click to set the home=Clique para definir a casa
|
||||
Prince Crown=A coroa do príncipe
|
||||
Prince of North Coat=Jaqueta do Príncipe do Norte
|
||||
Queen Ant=Formiga Rainha
|
||||
Queen Bee=Abelha Rainha
|
||||
Rabbit Hide=Couro de coelho
|
||||
Rat=Rato
|
||||
Raw Chicken=Frango cru
|
||||
Raw Ducky=Pato cru
|
||||
Raw Goat=Caprino cru
|
||||
Raw Parrot=Papagaio Cru
|
||||
Raw Porkchop=Costeleta de porco crua
|
||||
Raw Rabbit=Coelho cru
|
||||
Roasted Chicken=Frango Assado
|
||||
Roasted Chicken Legs=Coxas de frango assado
|
||||
Roasted Ducky=Pato assado
|
||||
|
@ -179,6 +186,7 @@ Roasted Goat Meat=Carne assada de caprino
|
|||
Roasted Lamb Chop=Costeleta de cordeiro assada
|
||||
Roasted Parrot=Papagaio Assado
|
||||
Roasted Porkchop=Costeleta de porco assada
|
||||
Roasted Rabbit=Coelho assado
|
||||
Rooster=Galo
|
||||
Saddle=Sela
|
||||
Saddlebag=Sacos de Sela
|
||||
|
|
|
@ -13,6 +13,7 @@ Anthill Entrance=Eingang zum Ameisenhügel
|
|||
Alight=Absteigen
|
||||
A silk bobbin has been created!=Eine Seidenspule wurde erstellt!
|
||||
Amount=Amount
|
||||
Automatic Go back home=Automatisch Nach Hause gehen
|
||||
Bat=Fledermaus
|
||||
Beaver Fur=Bieberpelz
|
||||
Beaver Oil=Bieberöl
|
||||
|
@ -34,6 +35,7 @@ Blueberry Muffin=Blaubeermuffin
|
|||
Bone=Knochen
|
||||
Bottle with Moth=Flasche mit Motte
|
||||
Brushed=Gebürstet
|
||||
Bunny=Kaninchen
|
||||
Butterfly=Schmetterling
|
||||
Butterfly Showcase=Schmetterling-Vitrine
|
||||
Buy=Kaufen
|
||||
|
@ -100,6 +102,8 @@ has starved to death!!!=ist verhungert!!!
|
|||
Health=Gesundheit
|
||||
Hen=Henne
|
||||
Herding=Hüten
|
||||
Home=Zuhause
|
||||
Home Pos=Ausgangsposition
|
||||
Honey=Honig
|
||||
Honeycomb=Honigwabe
|
||||
Honey Bottle=Honigglas
|
||||
|
@ -161,10 +165,12 @@ Poop Block=Mistblock
|
|||
Pregnant=Trächtig
|
||||
Pumpkin Hood=Kürbishaube
|
||||
Puppy=Hündchen
|
||||
Click to set the home=Klicken Sie auf, um die Heimat einzustellen.
|
||||
Prince Crown=Prinzenkrone
|
||||
Prince of North Coat=Umhang des Prinz des Nordens
|
||||
Queen Ant=Ameisenkönigin
|
||||
Queen Bee=Bienenkönigin
|
||||
Rabbit Hide=Kaninchenfell
|
||||
Rat=Ratte
|
||||
Raw Chicken=Rohes Hühnchen
|
||||
Raw Ducky=Rohes Entlein
|
||||
|
@ -172,6 +178,7 @@ Raw Goat=Rohes Ziege
|
|||
Raw Parrot=Roher Papagei
|
||||
Raw Porkchop=Rohes Schweinekotelett
|
||||
Roasted Chicken=Gebratenes Hühnchen
|
||||
Raw Rabbit=Rohe Kaninchen
|
||||
Roasted Chicken Legs=Gebratene Hühnchenkeule
|
||||
Roasted Ducky=Gebratenes Entlein
|
||||
Roasted Frog Leg=Gebratener Froschschenkel
|
||||
|
@ -179,6 +186,7 @@ Roasted Goat Meat=Gebratenes Ziegenfleisch
|
|||
Roasted Lamb Chop=Gebratene Lammkeule
|
||||
Roasted Parrot=Gebratener Papagei
|
||||
Roasted Porkchop=Gebratenes Schweinekotelett
|
||||
Roasted Rabbit=Gebratenes Kaninchen
|
||||
Rooster=Hahn
|
||||
Saddle=Sattel
|
||||
Saddlebag=Satteltasche
|
||||
|
|