1
0
mirror of https://github.com/adrido/darkage.git synced 2025-01-09 17:30:19 +01:00

version 1.0

bugfixes
compatibility and dependence with moreblocks added
2 new blocks
This commit is contained in:
adrido 2013-05-08 06:23:49 +02:00
parent c29eeaecfd
commit 082ae7190f
7 changed files with 1460 additions and 944 deletions

View File

@ -1,6 +1,49 @@
minetest.register_node("darkage:glass", {
description = "medieval Glass",
drawtype = "glasslike",
tiles = {"darkage_glass.png"},
inventory_image = minetest.inventorycube("darkage_glass.png"),
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults(),
})
minetest.register_node("darkage:glow_glass", {
description = "medieval glow glass",
drawtype = "glasslike",
tiles = {"darkage_glass.png"},
inventory_image = minetest.inventorycube("darkage_glass.png"),
paramtype = "light",
light_source = 18,
sunlight_propagates = true,
is_ground_content = true,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults(),
})
minetest.register_craft({
output = 'darkage:glow_glass 1',
recipe = {
{'darkage:glass', '', ''},
{'default:torch', '', ''},
{'', '', ''},
}
})
minetest.register_craft({
output = 'darkage:glass 8',
recipe = {
{'default:glass', 'default:steel_ingot', 'default:glass'},
{'default:steel_ingot', 'default:glass', 'default:steel_ingot'},
{'default:glass', 'default:steel_ingot', 'default:glass'},
}
})
minetest.register_node("darkage:reinforced_chalk", { minetest.register_node("darkage:reinforced_chalk", {
description = "Reinforced Chalk", description = "Reinforced Chalk",
tiles = {"darkage_reinforced_chalk.png"}, tiles = {"darkage_chalk.png^darkage_reinforce.png"},
is_ground_content = true, is_ground_content = true,
groups = {cracky=3}, groups = {cracky=3},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
@ -8,7 +51,7 @@ minetest.register_node("darkage:reinforced_chalk", {
minetest.register_node("darkage:reinforced_wood", { minetest.register_node("darkage:reinforced_wood", {
description = "Reinforced Wood", description = "Reinforced Wood",
tiles = {"darkage_reinforced_wood.png"}, tiles = {"default_wood.png^darkage_reinforce.png"},
is_ground_content = true, is_ground_content = true,
groups = {snappy=2,choppy=3,oddly_breakable_by_hand=3,flammable=3}, groups = {snappy=2,choppy=3,oddly_breakable_by_hand=3,flammable=3},
sounds = default.node_sound_wood_defaults() sounds = default.node_sound_wood_defaults()
@ -31,15 +74,6 @@ minetest.register_node("darkage:reinforced_wood_left", {
}) })
minetest.register_node("darkage:reinforced_wood", {
description = "Reinforced Wood",
tiles = {"darkage_reinforced_wood.png"},
is_ground_content = true,
groups = {snappy=2,choppy=3,oddly_breakable_by_hand=3,flammable=3},
sounds = default.node_sound_stone_defaults()
})
minetest.register_craft({ minetest.register_craft({
output = 'darkage:reinforced_chalk', output = 'darkage:reinforced_chalk',
recipe = { recipe = {
@ -49,6 +83,15 @@ minetest.register_craft({
} }
}) })
minetest.register_craft({
output = 'darkage:chalk',
recipe = {
{'darkage:chalk_powder','darkage:chalk_powder',''},
{'darkage:chalk_powder','darkage:chalk_powder',''},
{'','',''},
}
})
minetest.register_craft({ minetest.register_craft({
output = 'darkage:reinforced_wood', output = 'darkage:reinforced_wood',
recipe = { recipe = {

View File

@ -1,2 +1,2 @@
default default
moreblocks moreblocks

View File

@ -1,283 +1,283 @@
minetest.register_node("darkage:chain", { minetest.register_node("darkage:chain", {
description = "Chain", description = "Chain",
drawtype = "signlike", drawtype = "signlike",
tiles = {"darkage_chain.png"}, tiles = {"darkage_chain.png"},
inventory_image = "darkage_chain.png", inventory_image = "darkage_chain.png",
wield_image = "darkage_chain.png", wield_image = "darkage_chain.png",
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
is_ground_content = true, is_ground_content = true,
walkable = false, walkable = false,
climbable = true, climbable = true,
selection_box = { selection_box = {
type = "wallmounted", type = "wallmounted",
--wall_top = = <default> --wall_top = = <default>
--wall_bottom = = <default> --wall_bottom = = <default>
--wall_side = = <default> --wall_side = = <default>
}, },
groups = {snappy=1,cracky=2,oddly_breakable_by_hand=2}, groups = {snappy=1,cracky=2,oddly_breakable_by_hand=2},
legacy_wallmounted = true legacy_wallmounted = true
}) })
minetest.register_node('darkage:box', { minetest.register_node('darkage:box', {
description = "Box", description = "Box",
tiles = { 'darkage_box_top.png','darkage_box_top.png','darkage_box.png'}, tiles = { 'darkage_box_top.png','darkage_box_top.png','darkage_box.png'},
sunlight_propagates = false, sunlight_propagates = false,
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
groups = { snappy = 3 }, groups = { snappy = 3 },
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_wood_defaults(),
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.env:get_meta(pos) local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", meta:set_string("formspec",
"size[8,8]".. "size[8,8]"..
"list[current_name;main;0,0;8,3;]".. "list[current_name;main;0,0;8,3;]"..
"list[current_player;main;0,4;8,4;]") "list[current_player;main;0,4;8,4;]")
meta:set_string("infotext", "Box") meta:set_string("infotext", "Box")
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 16) inv:set_size("main", 16)
end, end,
can_dig = function(pos,player) can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos); local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:is_empty("main") return inv:is_empty("main")
end, end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" moves stuff in box at "..minetest.pos_to_string(pos)) " moves stuff in box at "..minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_put = function(pos, listname, index, stack, player) on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" moves stuff to box at "..minetest.pos_to_string(pos)) " moves stuff to box at "..minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_take = function(pos, listname, index, stack, player) on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" takes stuff from box at "..minetest.pos_to_string(pos)) " takes stuff from box at "..minetest.pos_to_string(pos))
end, end,
}) })
minetest.register_node('darkage:wood_shelves', { minetest.register_node('darkage:wood_shelves', {
description = "Wooden Shelves", description = "Wooden Shelves",
tiles = { 'darkage_shelves.png','darkage_shelves.png','darkage_shelves.png', tiles = { 'darkage_shelves.png','darkage_shelves.png','darkage_shelves.png',
'darkage_shelves.png','darkage_shelves.png','darkage_shelves_front.png'}, 'darkage_shelves.png','darkage_shelves.png','darkage_shelves_front.png'},
sunlight_propagates = false, sunlight_propagates = false,
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
groups = { snappy = 3 }, groups = { snappy = 3 },
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_wood_defaults(),
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.env:get_meta(pos) local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", meta:set_string("formspec",
"size[8,10]".. "size[8,10]"..
"list[context;up;0,0;8,3;]".. "list[context;up;0,0;8,3;]"..
"list[context;down;0,3;8,3;]".. "list[context;down;0,3;8,3;]"..
"list[current_player;main;0,6;8,4;]") "list[current_player;main;0,6;8,4;]")
meta:set_string("infotext", "Wooden Shelves") meta:set_string("infotext", "Wooden Shelves")
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("up", 16) inv:set_size("up", 16)
inv:set_size("down", 16) inv:set_size("down", 16)
end, end,
can_dig = function(pos,player) can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos); local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:is_empty("shape") and inv:is_empty("out") and inv:is_empty("water") return inv:is_empty("shape") and inv:is_empty("out") and inv:is_empty("water")
end, end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" moves stuff in shelves at "..minetest.pos_to_string(pos)) " moves stuff in shelves at "..minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_put = function(pos, listname, index, stack, player) on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" moves stuff to shelves at "..minetest.pos_to_string(pos)) " moves stuff to shelves at "..minetest.pos_to_string(pos))
end, end,
on_metadata_inventory_take = function(pos, listname, index, stack, player) on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name().. minetest.log("action", player:get_player_name()..
" takes stuff from shelves at "..minetest.pos_to_string(pos)) " takes stuff from shelves at "..minetest.pos_to_string(pos))
end, end,
}) })
--minetest.register_node("darkage:rosace", { --minetest.register_node("darkage:rosace", {
-- description = "Rose Window", -- description = "Rose Window",
-- tiles = {"darkage_rosace.png"}, -- tiles = {"darkage_rosace.png"},
-- is_ground_content = true, -- is_ground_content = true,
-- groups = {cracky=3}, -- groups = {cracky=3},
-- sounds = default.node_sound_stone_defaults() -- sounds = default.node_sound_stone_defaults()
--}) --})
minetest.register_node("darkage:iron_bars", { minetest.register_node("darkage:iron_bars", {
description = "Iron Bars", description = "Iron Bars",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"darkage_iron_bars.png"}, tiles = {"darkage_iron_bars.png"},
inventory_image = "darkage_iron_bars.png", inventory_image = "darkage_iron_bars.png",
wield_image = "darkage_iron_bars.png", wield_image = "darkage_iron_bars.png",
is_ground_content = true, is_ground_content = true,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {cracky=3}, groups = {cracky=3},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })
minetest.register_node("darkage:lamp", { minetest.register_node("darkage:lamp", {
description = "Lamp", description = "Lamp",
tiles = { tiles = {
"darkage_lamp.png" "darkage_lamp.png"
}, },
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
light_source = LIGHT_MAX-1, light_source = LIGHT_MAX-1,
groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,flammable=1}, groups = {snappy=2,cracky=3,oddly_breakable_by_hand=3,flammable=1},
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
}) })
minetest.register_node("darkage:iron_grille", { minetest.register_node("darkage:iron_grille", {
description = "Iron Grille", description = "Iron Grille",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"darkage_iron_grille.png"}, tiles = {"darkage_iron_grille.png"},
inventory_image = "darkage_iron_grille.png", inventory_image = "darkage_iron_grille.png",
wield_image = "darkage_iron_grille.png", wield_image = "darkage_iron_grille.png",
is_ground_content = true, is_ground_content = true,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {cracky=3}, groups = {cracky=3},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })
minetest.register_node("darkage:wood_bars", { minetest.register_node("darkage:wood_bars", {
description = "Wooden Bars", description = "Wooden Bars",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"darkage_wood_bars.png"}, tiles = {"darkage_wood_bars.png"},
inventory_image = "darkage_wood_bars.png", inventory_image = "darkage_wood_bars.png",
wield_image = "darkage_wood_bars.png", wield_image = "darkage_wood_bars.png",
is_ground_content = true, is_ground_content = true,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {snappy=1,choppy=2}, groups = {snappy=1,choppy=2},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })
minetest.register_node("darkage:wood_grille", { minetest.register_node("darkage:wood_grille", {
description = "Wooden Grille", description = "Wooden Grille",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"darkage_wood_grille.png"}, tiles = {"darkage_wood_grille.png"},
inventory_image = "darkage_wood_grille.png", inventory_image = "darkage_wood_grille.png",
wield_image = "darkage_wood_grille.png", wield_image = "darkage_wood_grille.png",
is_ground_content = true, is_ground_content = true,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {snappy=1,choppy=2}, groups = {snappy=1,choppy=2},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })
minetest.register_node("darkage:wood_frame", { minetest.register_node("darkage:wood_frame", {
description = "Wooden Frame", description = "Wooden Frame",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"darkage_wood_frame.png"}, tiles = {"darkage_wood_frame.png"},
inventory_image = "darkage_wood_frame.png", inventory_image = "darkage_wood_frame.png",
wield_image = "darkage_wood_frame.png", wield_image = "darkage_wood_frame.png",
is_ground_content = true, is_ground_content = true,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {snappy=1,choppy=2}, groups = {snappy=1,choppy=2},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })
--------------- ---------------
-- Crafts Item -- Crafts Item
--------------- ---------------
---------- ----------
-- Crafts -- Crafts
---------- ----------
minetest.register_craft({ minetest.register_craft({
output = 'darkage:box', output = 'darkage:box',
recipe = { recipe = {
{'default:wood','','default:wood'}, {'default:wood','','default:wood'},
{'','',''}, {'','',''},
{'default:wood','','default:wood'}, {'default:wood','','default:wood'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:chain 2', output = 'darkage:chain 2',
recipe = { recipe = {
{'darkage:iron_stick'}, --changed reziep to avoid problems with ironbars - addi {'darkage:iron_stick'}, --changed reziep to avoid problems with ironbars - addi
{'darkage:iron_stick'}, {'darkage:iron_stick'},
{'darkage:iron_stick'}, {'darkage:iron_stick'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:iron_bars 2', output = 'darkage:iron_bars 2',
recipe = { recipe = {
{'darkage:iron_stick','','darkage:iron_stick'}, --changed reziep to avoid problems with 3dfurniture -addi {'darkage:iron_stick','','darkage:iron_stick'}, --changed reziep to avoid problems with 3dfurniture -addi
{'darkage:iron_stick','','darkage:iron_stick'}, {'darkage:iron_stick','','darkage:iron_stick'},
{'darkage:iron_stick','','darkage:iron_stick'}, {'darkage:iron_stick','','darkage:iron_stick'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:iron_grille 3', output = 'darkage:iron_grille 3',
recipe = { recipe = {
{'','darkage:iron_bars',''}, {'','darkage:iron_bars',''},
{'darkage:iron_bars','','darkage:iron_bars'}, {'darkage:iron_bars','','darkage:iron_bars'},
{'','darkage:iron_bars',''}, {'','darkage:iron_bars',''},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:lamp', output = 'darkage:lamp',
recipe = { recipe = {
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
{'','default:torch',''}, {'','default:torch',''},
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:wood_bars 2', output = 'darkage:wood_bars 2',
recipe = { recipe = {
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:wood_grille 3', output = 'darkage:wood_grille 3',
recipe = { recipe = {
{'','darkage:wood_bars',''}, {'','darkage:wood_bars',''},
{'darkage:wood_bars','','darkage:wood_bars'}, {'darkage:wood_bars','','darkage:wood_bars'},
{'','darkage:wood_bars',''}, {'','darkage:wood_bars',''},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:wood_shelves', output = 'darkage:wood_shelves',
recipe = { recipe = {
{'darkage:box'}, {'darkage:box'},
{'darkage:box'}, {'darkage:box'},
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = 'darkage:wood_frame', output = 'darkage:wood_frame',
recipe = { recipe = {
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
{'','default:glass',''}, {'','default:glass',''},
{'default:stick','','default:stick'}, {'default:stick','','default:stick'},
} }
}) })
-- Cookings -- Cookings
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "default:glass", output = "default:glass",
recipe = "darkage:wood_frame", recipe = "darkage:wood_frame",
}) })

1633
init.lua

File diff suppressed because it is too large Load Diff

View File

@ -1,111 +1,17 @@
darkage = {} darkage = {};
function darkage.register_stairs(modname, subname, groups, images, desc)
function darkage.register_stairs(modname, item, groups, images, description) table.insert(circular_saw.known_stairs, modname..":"..subname);
local recipeitem = modname..":"..item recipeitem = modname..":"..subname;
local itemname = modname..":stair_"..item desc_stair = desc.." stair";
minetest.register_node(itemname, { desc_slab = desc.." slab";
description = description.." stair", desc_panel = desc.." panel";
drawtype = "nodebox", desc_micro = desc.." micro";
tiles = images, drop = subname
paramtype = "light", register_stair(modname, subname, recipeitem, groups, images, desc_stair, drop)
paramtype2 = "facedir", register_slab(modname, subname, recipeitem, groups, images, desc_slab, drop)
is_ground_content = true, register_panel(modname, subname, recipeitem, groups, images, desc_panel, drop)
groups = groups, register_micro(modname, subname, recipeitem, groups, images, desc_micro, drop)
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
{-0.5, 0, 0, 0.5, 0.5, 0.5},
},
},
})
minetest.register_craft({
output = itemname .. ' 4',
recipe = {
{recipeitem, "", ""},
{recipeitem, recipeitem, ""},
{recipeitem, recipeitem, recipeitem},
},
})
-- Flipped recipe for the silly minecrafters
minetest.register_craft({
output = itemname .. ' 4',
recipe = {
{"", "", recipeitem},
{"", recipeitem, recipeitem},
{recipeitem, recipeitem, recipeitem},
},
})
itemname=modname..":slab_" .. item
minetest.register_node(itemname, {
description = description.." slab",
drawtype = "nodebox",
tiles = images,
paramtype = "light",
is_ground_content = true,
groups = groups,
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
},
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
},
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
-- If it's being placed on an another similar one, replace it with
-- a full block
local slabpos = nil
local slabnode = nil
local p0 = pointed_thing.under
local p1 = pointed_thing.above
local n0 = minetest.env:get_node(p0)
local n1 = minetest.env:get_node(p1)
if n0.name == itemname then
slabpos = p0
slabnode = n0
elseif n1.name == itemname then
slabpos = p1
slabnode = n1
end
if slabpos then
-- Remove the slab at slabpos
minetest.env:remove_node(slabpos)
-- Make a fake stack of a single item and try to place it
local fakestack = ItemStack(recipeitem)
pointed_thing.above = slabpos
fakestack = minetest.item_place(fakestack, placer, pointed_thing)
-- If the item was taken from the fake stack, decrement original
if not fakestack or fakestack:is_empty() then
itemstack:take_item(1)
-- Else put old node back
else
minetest.env:set_node(slabpos, slabnode)
end
return itemstack
end
-- Otherwise place regularly
return minetest.item_place(itemstack, placer, pointed_thing)
end,
})
minetest.register_craft({
output = itemname .. ' 3',
recipe = {
{recipeitem, recipeitem, recipeitem},
},
})
end end
darkage.register_stairs("darkage","basalt_cobble", darkage.register_stairs("darkage","basalt_cobble",
{cracky=3}, {cracky=3},
{"darkage_basalt_cobble.png"}, {"darkage_basalt_cobble.png"},
@ -142,3 +48,19 @@ darkage.register_stairs("darkage","desert_stone_cobble",
"Desert Stone Cobble" "Desert Stone Cobble"
) )
darkage.register_stairs("darkage","slate_cobble",
{cracky=3},
{"darkage_slate_cobble.png"},
"Slate Cobble"
)
darkage.register_stairs("darkage","sandstone_cobble",
{cracky=3},
{"darkage_sandstone_cobble.png"},
"Sandstone Cobble"
)
darkage.register_stairs("darkage","gneiss_cobble",
{cracky=3},
{"darkage_gneiss_cobble.png"},
"Gneiss Cobble"
)

BIN
textures/darkage_glass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B