updated castle, colormachine, homedecor, mesecons, pipeworks, signs_lib, technic, and xban2
@ -21,15 +21,37 @@ Contains as of now:
|
||||
--Castlestone Stairs, Slabs, and Pillars
|
||||
--Jailbars
|
||||
--Hides
|
||||
--Arrowslits
|
||||
--Rubble (for between walls)
|
||||
--Arrows and Arrowslits
|
||||
--Rubble
|
||||
--Doors
|
||||
--Weapons
|
||||
--Chandeliers
|
||||
--Tapestries
|
||||
--and more!
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=
|
||||
" Although crossbows have been removed, along with arrows, the code is still there.
|
||||
To get the crossbows back, look in init.lua. You will see at the top some lines
|
||||
with dofile in them. Copy and paste two more of these lines, and change them to
|
||||
crossbow.lua and arrow.lua to get them back. "
|
||||
|
||||
I, (philipbenr) will take a look at the arrows and crossbows, and see about this.
|
||||
Big release coming soon. ;) Stay tuned.
|
||||
|
||||
Planned features (anything with question mark means that I am either unsure or don't know how to accomplish it ;)
|
||||
|
||||
--More/Better weapons
|
||||
--More decorations
|
||||
--More nodes
|
||||
--Redone columns
|
||||
--More doors
|
||||
--Gatehouse mod
|
||||
--Armor
|
||||
--More magical items (mana, orbs, potions...)
|
||||
--Crowns/capes/player decor
|
||||
--Flags
|
||||
--Brewery/Liquor (liquor effects is another thing altogether)
|
||||
--Tannery?
|
||||
--Books? (that is an interesting one... I'll write a post on it later)
|
||||
--Guards?
|
||||
--Player status (King, queen, etc.)?
|
||||
--Foods?
|
||||
--Horses/Livestock?
|
||||
--Ruins?
|
||||
|
||||
--Modpack Configurator
|
||||
|
@ -26,7 +26,7 @@ for _, row in ipairs(arrowslit.types) do
|
||||
description = desc.." Arrowslit",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
@ -50,7 +50,7 @@ for _, row in ipairs(arrowslit.types) do
|
||||
description = desc.." Arrowslit with Cross",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
@ -78,7 +78,7 @@ for _, row in ipairs(arrowslit.types) do
|
||||
description = desc.." Arrowslit with Hole",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
|
@ -1,43 +1,431 @@
|
||||
arrows = {
|
||||
{"castle:arrow", "castle:arrow_entity"},
|
||||
--[[
|
||||
Minetest Mod - Simple Shooter [shooter] 0.5.3
|
||||
=======================================
|
||||
|
||||
License Source Code: 2013 Stuart Jones - LGPL v2.1
|
||||
|
||||
License Textures: Stuart Jones - WTFPL
|
||||
|
||||
Licence Models: Stuart Jones - CC-BY-SA 3.0
|
||||
|
||||
License Sounds: freesound.org
|
||||
|
||||
--]]
|
||||
local crossbow={}
|
||||
|
||||
minetest.register_alias("crossbow", "castle:crossbow")
|
||||
minetest.register_alias("bolt", "castle:crossbow_bolt")
|
||||
|
||||
CROSSBOW_USES = 300
|
||||
CROSSBOW_BOLT_TOOL_CAPS = {damage_groups={fleshy=4}}
|
||||
CROSSBOW_BOLT_LIFETIME = 60-- 1 minute
|
||||
CROSSBOW_ENABLE_PARTICLE_FX = false
|
||||
CROSSBOW_ENABLE_PROTECTION = true
|
||||
CROSSBOW_EXPLOSION_TEXTURE = "castle_crossbow_hit.png"
|
||||
CROSSBOW_ALLOW_NODES = true
|
||||
CROSSBOW_ALLOW_ENTITIES = true
|
||||
CROSSBOW_ALLOW_PLAYERS = true
|
||||
CROSSBOW_PLAYER_OFFSET = {x=0, y=1, z=0}
|
||||
CROSSBOW_ENTITY_OFFSET = {x=0, y=0, z=0}
|
||||
CROSSBOW_ENTITIES = {
|
||||
"mobs:chicken",
|
||||
"mobs:cow",
|
||||
"mobs:dirt_monster",
|
||||
"mobs:dungeon_master",
|
||||
"mobs:goat",
|
||||
"mobs:mese_monster",
|
||||
"mobs:npc",
|
||||
"mobs:oerkki",
|
||||
"mobs:pig",
|
||||
"mobs:pumba",
|
||||
"mobs:rat",
|
||||
"mobs:rhino",
|
||||
"mobs:sand_monster",
|
||||
"mobs:sheep",
|
||||
"mobs:spider",
|
||||
"mobs:stone_monster",
|
||||
"mobs:tree_monster",
|
||||
}
|
||||
|
||||
local castle_shoot_arrow = function(itemstack, player)
|
||||
for _,arrow in ipairs(arrows) do
|
||||
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
player:get_inventory():remove_item("main", arrow[1])
|
||||
end
|
||||
local playerpos = player:getpos()
|
||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow[2])
|
||||
local dir = player:get_look_dir()
|
||||
obj:setvelocity({x=dir.x*19, y=dir.y*19, z=dir.z*19})
|
||||
obj:setacceleration({x=dir.x*-3, y=-10, z=dir.z*-3})
|
||||
obj:setyaw(player:get_look_yaw()+math.pi)
|
||||
minetest.sound_play("castle_sound", {pos=playerpos})
|
||||
if obj:get_luaentity().player == "" then
|
||||
obj:get_luaentity().player = player
|
||||
end
|
||||
obj:get_luaentity().node = player:get_inventory():get_stack("main", 1):get_name()
|
||||
return true
|
||||
if minetest.is_singleplayer() == true then
|
||||
CROSSBOW_ALLOW_ENTITIES = true
|
||||
CROSSBOW_ALLOW_PLAYERS = true
|
||||
end
|
||||
|
||||
local allowed_entities = {}
|
||||
for _,v in ipairs(CROSSBOW_ENTITIES) do
|
||||
allowed_entities[v] = 1
|
||||
end
|
||||
|
||||
local function get_dot_product(v1, v2)
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
|
||||
end
|
||||
|
||||
local function get_particle_pos(p, v, d)
|
||||
return vector.add(p, vector.multiply(v, {x=d, y=d, z=d}))
|
||||
end
|
||||
|
||||
function crossbow:spawn_particles(pos, texture)
|
||||
if CROSSBOW_ENABLE_PARTICLE_FX == true then
|
||||
if type(texture) ~= "string" then
|
||||
texture = CROSSBOW_EXPLOSION_TEXTURE
|
||||
end
|
||||
local spread = {x=0.1, y=0.1, z=0.1}
|
||||
minetest.add_particlespawner(15, 0.3,
|
||||
vector.subtract(pos, spread), vector.add(pos, spread),
|
||||
{x=-1, y=1, z=-1}, {x=1, y=2, z=1},
|
||||
{x=-2, y=-2, z=-2}, {x=2, y=-2, z=2},
|
||||
0.1, 0.75, 1, 2, false, texture
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function crossbow:punch_node(pos, def)
|
||||
local node = minetest.get_node(pos)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
local item = minetest.registered_items[node.name]
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
if CROSSBOW_ENABLE_PROTECTION then
|
||||
if minetest.is_protected(pos, def.name) then
|
||||
return
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
minetest.register_tool("castle:crossbow", {
|
||||
description = "Crossbow",
|
||||
inventory_image = "castle_crossbow.png",
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if castle_shoot_arrow(item, user, pointed_thing) then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/200)
|
||||
if item.groups then
|
||||
for k, v in pairs(def.groups) do
|
||||
local level = item.groups[k] or 0
|
||||
if level >= v then
|
||||
minetest.remove_node(pos)
|
||||
if item.tiles then
|
||||
if item.tiles[1] then
|
||||
crossbow:spawn_particles(pos, item.tiles[1])
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
function crossbow:is_valid_object(object)
|
||||
if object then
|
||||
if object:is_player() == true then
|
||||
return CROSSBOW_ALLOW_PLAYERS
|
||||
end
|
||||
if CROSSBOW_ALLOW_ENTITIES == true then
|
||||
local luaentity = object:get_luaentity()
|
||||
if luaentity then
|
||||
if luaentity.name then
|
||||
if allowed_entities[luaentity.name] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function crossbow:get_intersect_pos(ray, plane, collisionbox)
|
||||
local v = vector.subtract(ray.pos, plane.pos)
|
||||
local r1 = get_dot_product(v, plane.normal)
|
||||
local r2 = get_dot_product(ray.dir, plane.normal)
|
||||
if r2 ~= 0 then
|
||||
local t = -(r1 / r2)
|
||||
local td = vector.multiply(ray.dir, {x=t, y=t, z=t})
|
||||
local pt = vector.add(ray.pos, td)
|
||||
local pd = vector.subtract(pt, plane.pos)
|
||||
if math.abs(pd.x) < collisionbox[4] and
|
||||
math.abs(pd.y) < collisionbox[5] and
|
||||
math.abs(pd.z) < collisionbox[6] then
|
||||
return pt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function crossbow:process_round(round)
|
||||
local target = {object=nil, distance=10000}
|
||||
local p1 = round.pos
|
||||
local v1 = round.ray
|
||||
for _,ref in ipairs(castle.objects) do
|
||||
local p2 = vector.add(ref.pos, ref.offset)
|
||||
if p1 and p2 and ref.name ~= round.name then
|
||||
local d = vector.distance(p1, p2)
|
||||
if d < round.def.step and d < target.distance then
|
||||
local ray = {pos=p1, dir=v1}
|
||||
local plane = {pos=p2, normal={x=-1, y=0, z=-1}}
|
||||
local pos = crossbow:get_intersect_pos(ray, plane, ref.collisionbox)
|
||||
if pos then
|
||||
target.object = ref.object
|
||||
target.pos = pos
|
||||
target.distance = d
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if target.object and target.pos then
|
||||
local success, pos = minetest.line_of_sight(p1, target.pos, 1)
|
||||
if success then
|
||||
local user = minetest.get_player_by_name(round.name)
|
||||
if user then
|
||||
target.object:punch(user, nil, round.def.tool_caps, v1)
|
||||
crossbow:spawn_particles(target.pos, CROSSBOW_EXPLOSION_TEXTURE)
|
||||
end
|
||||
return 1
|
||||
elseif pos and CROSSBOW_ALLOW_NODES == true then
|
||||
crossbow:punch_node(pos, round.def)
|
||||
return 1
|
||||
end
|
||||
elseif CROSSBOW_ALLOW_NODES == true then
|
||||
local d = round.def.step
|
||||
local p2 = vector.add(p1, vector.multiply(v1, {x=d, y=d, z=d}))
|
||||
local success, pos = minetest.line_of_sight(p1, p2, 1)
|
||||
if pos then
|
||||
crossbow:punch_node(pos, round.def)
|
||||
return 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_animation_frame(dir)
|
||||
local angle = math.atan(dir.y)
|
||||
local frame = 90 - math.floor(angle * 360 / math.pi)
|
||||
if frame < 1 then
|
||||
frame = 1
|
||||
elseif frame > 180 then
|
||||
frame = 180
|
||||
end
|
||||
return frame
|
||||
end
|
||||
|
||||
local function get_target_pos(p1, p2, dir, offset)
|
||||
local d = vector.distance(p1, p2) - offset
|
||||
local td = vector.multiply(dir, {x=d, y=d, z=d})
|
||||
return vector.add(p1, td)
|
||||
end
|
||||
|
||||
local function punch_object(puncher, object)
|
||||
if puncher and crossbow:is_valid_object(object) then
|
||||
if puncher ~= object then
|
||||
local dir = puncher:get_look_dir()
|
||||
local p1 = puncher:getpos()
|
||||
local p2 = object:getpos()
|
||||
local tpos = get_target_pos(p1, p2, dir, 0)
|
||||
crossbow:spawn_particles(tpos, CROSSBOW_EXPLOSION_TEXTURE)
|
||||
object:punch(puncher, nil, CROSSBOW_BOLT_TOOL_CAPS, dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function stop_crossbow_bolt(object, pos, stuck)
|
||||
local acceleration = {x=0, y=-10, z=0}
|
||||
if stuck == true then
|
||||
pos = pos or object:getpos()
|
||||
acceleration = {x=0, y=0, z=0}
|
||||
object:moveto(pos)
|
||||
end
|
||||
object:set_properties({
|
||||
physical = true,
|
||||
collisionbox = {-1/8,-1/8,-1/8, 1/8,1/8,1/8},
|
||||
})
|
||||
object:setvelocity({x=0, y=0, z=0})
|
||||
object:setacceleration(acceleration)
|
||||
end
|
||||
|
||||
minetest.register_craftitem("castle:crossbow_bolt", {
|
||||
description = "Bolt",
|
||||
stack_max = 20,
|
||||
inventory_image = "castle_crossbow_bolt_inv.png",
|
||||
})
|
||||
|
||||
minetest.register_entity("castle:crossbow_bolt_entity", {
|
||||
physical = false,
|
||||
visual = "mesh",
|
||||
mesh = "castle_crossbow_bolt.b3d",
|
||||
visual_size = {x=1.0, y=1.0},
|
||||
textures = {
|
||||
"castle_crossbow_bolt_uv.png"
|
||||
},
|
||||
timer = 0,
|
||||
lifetime = CROSSBOW_BOLT_LIFETIME,
|
||||
player = nil,
|
||||
state = "init",
|
||||
node_pos = nil,
|
||||
collisionbox = {0,0,0, 0,0,0},
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
if staticdata == "expired" then
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
on_punch = function(self, puncher)
|
||||
if puncher then
|
||||
if puncher:is_player() then
|
||||
local stack = "castle:crossbow_bolt"
|
||||
local inv = puncher:get_inventory()
|
||||
if inv:room_for_item("main", stack) then
|
||||
inv:add_item("main", stack)
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
if self.state == "init" then
|
||||
return
|
||||
end
|
||||
self.timer = self.timer + dtime
|
||||
self.lifetime = self.lifetime - dtime
|
||||
if self.lifetime < 0 then
|
||||
self.object:remove()
|
||||
return
|
||||
elseif self.state == "dropped" then
|
||||
return
|
||||
elseif self.state == "stuck" then
|
||||
if self.timer > 1 then
|
||||
if self.node_pos then
|
||||
local node = minetest.get_node(self.node_pos)
|
||||
if node.name then
|
||||
local item = minetest.registered_items[node.name]
|
||||
if item then
|
||||
if not item.walkable then
|
||||
self.state = "dropped"
|
||||
stop_crossbow_bolt(self.object)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.timer = 0
|
||||
end
|
||||
return
|
||||
end
|
||||
if self.timer > 0.2 then
|
||||
local pos = self.object:getpos()
|
||||
local dir = vector.normalize(self.object:getvelocity())
|
||||
local frame = get_animation_frame(dir)
|
||||
self.object:set_animation({x=frame, y=frame}, 0)
|
||||
local objects = minetest.get_objects_inside_radius(pos, 5)
|
||||
for _,obj in ipairs(objects) do
|
||||
if crossbow:is_valid_object(obj) then
|
||||
local collisionbox = {-0.25,-1.0,-0.25, 0.25,0.8,0.25}
|
||||
local offset = CROSSBOW_PLAYER_OFFSET
|
||||
if not obj:is_player() then
|
||||
offset = CROSSBOW_ENTITY_OFFSET
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
local def = minetest.registered_entities[ent.name]
|
||||
collisionbox = def.collisionbox or collisionbox
|
||||
end
|
||||
end
|
||||
local opos = vector.add(obj:getpos(), offset)
|
||||
local ray = {pos=pos, dir=dir}
|
||||
local plane = {pos=opos, normal={x=-1, y=0, z=-1}}
|
||||
local ipos = crossbow:get_intersect_pos(ray, plane, collisionbox)
|
||||
if ipos then
|
||||
punch_object(self.player, obj)
|
||||
end
|
||||
end
|
||||
end
|
||||
local p = vector.add(pos, vector.multiply(dir, {x=5, y=5, z=5}))
|
||||
local _, npos = minetest.line_of_sight(pos, p, 1)
|
||||
if npos then
|
||||
local node = minetest.get_node(npos)
|
||||
local tpos = get_target_pos(pos, npos, dir, 0.66)
|
||||
self.node_pos = npos
|
||||
self.state = "stuck"
|
||||
stop_crossbow_bolt(self.object, tpos, true)
|
||||
minetest.sound_play("castle_crossbow_bolt", {gain = 0.08, max_hear_distance = 2})
|
||||
end
|
||||
self.timer = 0
|
||||
end
|
||||
end,
|
||||
get_staticdata = function(self)
|
||||
return "expired"
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_tool("castle:crossbow_loaded", {
|
||||
description = "Crossbow",
|
||||
inventory_image = "castle_crossbow_loaded.png",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
minetest.sound_play("castle_crossbow_click", {object=user})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/CROSSBOW_USES)
|
||||
end
|
||||
itemstack = "castle:crossbow 1 "..itemstack:get_wear()
|
||||
local pos = user:getpos()
|
||||
local dir = user:get_look_dir()
|
||||
local yaw = user:get_look_yaw()
|
||||
if pos and dir and yaw then
|
||||
pos.y = pos.y + 1.5
|
||||
local obj = minetest.add_entity(pos, "castle:crossbow_bolt_entity")
|
||||
local ent = nil
|
||||
if obj then
|
||||
ent = obj:get_luaentity()
|
||||
end
|
||||
if ent then
|
||||
obj:set_properties({
|
||||
textures = {"castle_crossbow_bolt_uv.png"}
|
||||
})
|
||||
minetest.sound_play("castle_crossbow_shoot", {object=obj})
|
||||
local frame = get_animation_frame(dir)
|
||||
obj:setyaw(yaw + math.pi)
|
||||
obj:set_animation({x=frame, y=frame}, 0)
|
||||
obj:setvelocity({x=dir.x * 14, y=dir.y * 14, z=dir.z * 14})
|
||||
if pointed_thing.type ~= "nothing" then
|
||||
local ppos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
local _, npos = minetest.line_of_sight(pos, ppos, 1)
|
||||
if npos then
|
||||
ppos = npos
|
||||
pointed_thing.type = "node"
|
||||
end
|
||||
if pointed_thing.type == "object" then
|
||||
punch_object(user, pointed_thing.ref)
|
||||
elseif pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(ppos)
|
||||
local tpos = get_target_pos(pos, ppos, dir, 0.66)
|
||||
minetest.after(0.2, function(object, pos, npos)
|
||||
ent.node_pos = npos
|
||||
ent.state = "stuck"
|
||||
stop_crossbow_bolt(object, pos, true)
|
||||
minetest.sound_play("castle_crossbow_bolt", {gain = 0.08, max_hear_distance = 2})
|
||||
end, obj, tpos, ppos)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
obj:setacceleration({x=dir.x * -3, y=-5, z=dir.z * -3})
|
||||
ent.player = ent.player or user
|
||||
ent.state = "flight"
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_tool("castle:crossbow", {
|
||||
description = "Crossbow",
|
||||
inventory_image = "castle_crossbow_inv.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local inv = user:get_inventory()
|
||||
if inv:contains_item("main", "castle:crossbow_bolt") then
|
||||
minetest.sound_play("castle_crossbow_reload", {object=user})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
inv:remove_item("main", "castle:crossbow_bolt 1")
|
||||
end
|
||||
return "castle:crossbow_loaded 1 "..itemstack:get_wear()
|
||||
end
|
||||
minetest.sound_play("castle_crossbow_click", {object=user})
|
||||
end,
|
||||
})
|
||||
|
||||
-----------
|
||||
--Crafting
|
||||
-----------
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'castle:crossbow',
|
||||
recipe = {
|
||||
@ -46,3 +434,10 @@ minetest.register_craft({
|
||||
{'', 'default:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "castle:crossbow_bolt 6",
|
||||
recipe = {
|
||||
{'default:stick', 'default:stick', 'default:steel_ingot'},
|
||||
}
|
||||
})
|
131
castle/init.lua
@ -7,6 +7,7 @@ dofile(minetest.get_modpath("castle").."/shields_decor.lua")
|
||||
dofile(minetest.get_modpath("castle").."/murder_hole.lua")
|
||||
dofile(minetest.get_modpath("castle").."/orbs.lua")
|
||||
dofile(minetest.get_modpath("castle").."/rope.lua")
|
||||
dofile(minetest.get_modpath("castle").."/crossbow.lua")
|
||||
|
||||
minetest.register_node("castle:stonewall", {
|
||||
description = "Castle Wall",
|
||||
@ -15,6 +16,7 @@ minetest.register_node("castle:stonewall", {
|
||||
paramtype = "light",
|
||||
drop = "castle:stonewall",
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("castle:rubble", {
|
||||
@ -23,6 +25,7 @@ minetest.register_node("castle:rubble", {
|
||||
tiles = {"castle_rubble.png"},
|
||||
paramtype = "light",
|
||||
groups = {crumbly=3,falling_node=1},
|
||||
sounds = default.node_sound_gravel_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -60,6 +63,7 @@ minetest.register_node("castle:stonewall_corner", {
|
||||
"castle_stonewall.png",
|
||||
"castle_corner_stonewall2.png"},
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -83,6 +87,7 @@ minetest.register_node("castle:roofslate", {
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
|
||||
},
|
||||
groups = {cracky=3,attached_node=1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("castle:hides", {
|
||||
@ -158,38 +163,6 @@ if not (mod_building_blocks or mod_streets) then
|
||||
|
||||
end
|
||||
|
||||
stairs.register_stair_and_slab("stonewall", "castle:stonewall",
|
||||
{cracky=3},
|
||||
{"castle_stonewall.png"},
|
||||
"Castle Wall Stair",
|
||||
"Castle Wall Slab",
|
||||
default.node_sound_stone_defaults())
|
||||
|
||||
minetest.register_craft({
|
||||
output = "castle:stairs 4",
|
||||
recipe = {
|
||||
{"castle:stonewall","",""},
|
||||
{"castle:stonewall","castle:stonewall",""},
|
||||
{"castle:stonewall","castle:stonewall","castle:stonewall"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:stair_stonewall 4",
|
||||
recipe = {
|
||||
{"","","castle:stonewall"},
|
||||
{"","castle:stonewall","castle:stonewall"},
|
||||
{"castle:stonewall","castle:stonewall","castle:stonewall"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:slab_stonewall 6",
|
||||
recipe = {
|
||||
{"castle:stonewall","castle:stonewall","castle:stonewall"},
|
||||
}
|
||||
})
|
||||
|
||||
doors.register("castle:oak_door", {
|
||||
tiles = {{ name = "castle_door_oak.png", backface_culling = true }},
|
||||
description = "Oak Door",
|
||||
@ -232,7 +205,14 @@ function default.get_ironbound_chest_formspec(pos)
|
||||
end
|
||||
|
||||
local function has_ironbound_chest_privilege(meta, player)
|
||||
if player:get_player_name() ~= meta:get_string("owner") then
|
||||
local name = ""
|
||||
if player then
|
||||
if minetest.check_player_privs(player, "protection_bypass") then
|
||||
return true
|
||||
end
|
||||
name = player:get_player_name()
|
||||
end
|
||||
if name ~= meta:get_string("owner") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
@ -374,26 +354,10 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
if minetest.get_modpath("moreblocks") then
|
||||
stairsplus:register_all("castle", "dungeon_stone", "castle:dungeon_stone", {
|
||||
description = "Dungeon Stone",
|
||||
tiles = {"castle_dungeon_stone.png"},
|
||||
groups = {cracky=1, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
stairsplus:register_all("castle", "pavement_brick", "castle:pavement_brick", {
|
||||
description = "Pavement Brick",
|
||||
tiles = {"castle_pavement_brick.png"},
|
||||
groups = {cracky=1, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
stairsplus:register_all("castle", "stonewall", "castle:stonewall", {
|
||||
description = "Stone Wall",
|
||||
tiles = {"castle_stonewall.png"},
|
||||
groups = {cracky=1, not_in_creative_inventory=1},
|
||||
groups = {cracky=3, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
@ -401,54 +365,25 @@ if minetest.get_modpath("moreblocks") then
|
||||
stairsplus:register_all("castle", "rubble", "castle:rubble", {
|
||||
description = "Rubble",
|
||||
tiles = {"castle_rubble.png"},
|
||||
groups = {cracky=1, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
groups = {cracky=3, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_gravel_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
else
|
||||
stairs.register_stair_and_slab("stonewall", "castle:stonewall",
|
||||
{cracky=3},
|
||||
{"castle_stonewall.png"},
|
||||
"Castle Stonewall Stair",
|
||||
"Castle Stonewall Slab",
|
||||
default.node_sound_stone_defaults()
|
||||
)
|
||||
|
||||
stairs.register_stair_and_slab("rubble", "castle:rubble",
|
||||
{cracky=3},
|
||||
{"castle_rubble.png"},
|
||||
"Castle Rubble Stair",
|
||||
"Castle Rubble Slab",
|
||||
default.node_sound_stone_defaults()
|
||||
)
|
||||
end
|
||||
|
||||
stairs.register_stair_and_slab("dungeon_stone", "castle:dungeon_stone",
|
||||
{cracky=3},
|
||||
{"castle_dungeon_stone.png"},
|
||||
"Dungeon Stone Stair",
|
||||
"Dungeon Stone Slab",
|
||||
default.node_sound_stone_defaults())
|
||||
|
||||
stairs.register_stair_and_slab("castle_pavement_brick", "castle:pavement_brick",
|
||||
{cracky=3},
|
||||
{"castle_pavement_brick.png"},
|
||||
"Castle Pavement Stair",
|
||||
"Castle Pavement Slab",
|
||||
default.node_sound_stone_defaults())
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:slab_dungeon_stone 6",
|
||||
recipe = {
|
||||
{"castle:dungeon_stone","castle:dungeon_stone","castle:dungeon_stone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:slab_pavement_brick 6",
|
||||
recipe = {
|
||||
{"castle:pavement_brick","castle:pavement_brick","castle:pavement_brick"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:stair_dungeon_stone 4",
|
||||
recipe = {
|
||||
{"","","castle:dungeon_stone"},
|
||||
{"","castle:dungeon_stone","castle:dungeon_stone"},
|
||||
{"castle:dungeon_stone","castle:dungeon_stone","castle:dungeon_stone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "stairs:stair_pavement_brick 4",
|
||||
recipe = {
|
||||
{"","","castle:pavement_brick"},
|
||||
{"","castle:pavement_brick","castle:pavement_brick"},
|
||||
{"castle:pavement_brick","castle:pavement_brick","castle:pavement_brick"},
|
||||
}
|
||||
})
|
||||
|
@ -14,3 +14,8 @@ if minetest.get_modpath("xpanes") then
|
||||
{"default:steel_ingot","","default:steel_ingot"}}
|
||||
})
|
||||
end
|
||||
|
||||
for i = 1, 15 do
|
||||
minetest.register_alias("castle:jailbars_"..i, "xpanes:jailbars_"..i)
|
||||
end
|
||||
minetest.register_alias("castle:jailbars", "xpanes:jailbars")
|
||||
|
10
castle/models/LICENSE.txt
Normal file
@ -0,0 +1,10 @@
|
||||
License Textures: Stuart Jones - WTFPL
|
||||
|
||||
-castle_crossbow_bolt_inv.png
|
||||
-castle_crossbow_bolt_uv.png
|
||||
-castle_crossbow_hit.png
|
||||
|
||||
Licence Models: Stuart Jones - CC-BY-SA 3.0
|
||||
|
||||
-castle_crossbow_bolt.b3d
|
||||
-castle_crossbow_bolt.blend
|
BIN
castle/models/castle_crossbow_bolt.b3d
Normal file
BIN
castle/models/castle_crossbow_bolt.blend
Normal file
BIN
castle/models/castle_crossbow_bolt_uv.png
Normal file
After Width: | Height: | Size: 157 B |
@ -22,7 +22,7 @@ for _, row in ipairs(hole.types) do
|
||||
description = desc.." Murder Hole",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
|
@ -26,7 +26,7 @@ for _, row in ipairs(pillar.types) do
|
||||
description = desc.." Pillar Base",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3,attached_node=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
@ -43,7 +43,7 @@ for _, row in ipairs(pillar.types) do
|
||||
description = desc.." Pillar Top",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3,attached_node=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
@ -61,7 +61,7 @@ for _, row in ipairs(pillar.types) do
|
||||
description = desc.." Pillar Middle",
|
||||
tiles = {tile..".png"},
|
||||
groups = {cracky=3,attached_node=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
|
@ -4,6 +4,7 @@ minetest.register_node("castle:ropes",{
|
||||
sunlight_propagates = true,
|
||||
tiles = {"castle_ropes.png"},
|
||||
groups = {choppy=3,snappy=3,oddly_breakable_by_hand=3,flammable=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
climbable = true,
|
||||
walkable = false,
|
||||
@ -73,6 +74,7 @@ minetest.register_node("castle:ropebox", {
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
@ -5,6 +5,7 @@ minetest.register_node("castle:shield",{
|
||||
paramtype2 = "facedir",
|
||||
paramtype = "light",
|
||||
groups={cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
@ -39,6 +40,7 @@ minetest.register_node("castle:shield_2",{
|
||||
paramtype2 = "facedir",
|
||||
paramtype = "light",
|
||||
groups={cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
@ -72,6 +74,7 @@ minetest.register_node("castle:shield_3",{
|
||||
paramtype2 = "facedir",
|
||||
paramtype = "light",
|
||||
groups={cracky=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
52
castle/sounds/LICENSE.txt
Normal file
@ -0,0 +1,52 @@
|
||||
License Sounds
|
||||
------------------
|
||||
|
||||
(From Simple Shooter mod by Stuart Jones)
|
||||
-castle_crossbow_click.ogg
|
||||
-castle_crossbow_shoot.ogg
|
||||
-castle_reload.ogg
|
||||
|
||||
Author : freesound.org
|
||||
License : Attribution 3.0 Unported (CC BY 3.0)
|
||||
CC0 1.0 Universal (CC0 1.0)
|
||||
|
||||
------------------
|
||||
|
||||
(From Minetest Game:default mod)
|
||||
-default_wood_footstep.1.ogg
|
||||
(renamed to : castle_crossbow_bolt.ogg)
|
||||
Author : Mito551
|
||||
License : (CC BY-SA)
|
||||
|
||||
------------------
|
||||
|
||||
Author: Brandon Morris
|
||||
file: castle_orbs.ogg
|
||||
original file : completetask_0.mp3
|
||||
http://opengameart.org/content/completion-sound
|
||||
License: CC-BY 3.0
|
||||
http://creativecommons.org/licenses/by/3.0/
|
||||
|
||||
------------------
|
||||
|
||||
(From Ambience mod)
|
||||
|
||||
Author: Mike Koenig
|
||||
file: castle_owl.ogg
|
||||
original file : horned_owl.ogg
|
||||
http://soundbible.com/1851-Horned-Owl.html
|
||||
License: Attribution 3.0
|
||||
http://creativecommons.org/licenses/by/3.0/
|
||||
|
||||
------------------
|
||||
|
||||
(From Ambience mod)
|
||||
|
||||
Author: PsychoBird
|
||||
file: castle_birds.ogg
|
||||
original file : Best Cardinal Bird.ogg
|
||||
http://soundbible.com/1515-Best-Cardinal-Bird.html
|
||||
License: Attribution 3.0
|
||||
http://creativecommons.org/licenses/by/3.0/
|
||||
|
||||
------------------
|
BIN
castle/sounds/castle_birds.ogg
Normal file
BIN
castle/sounds/castle_crossbow_bolt.ogg
Normal file
BIN
castle/sounds/castle_crossbow_click.ogg
Normal file
BIN
castle/sounds/castle_crossbow_shoot.ogg
Normal file
BIN
castle/sounds/castle_orbs.ogg
Normal file
BIN
castle/sounds/castle_owl.ogg
Normal file
BIN
castle/sounds/castle_reload.ogg
Normal file
@ -2,23 +2,23 @@ local tapestry = {}
|
||||
|
||||
minetest.register_node("castle:tapestry_top", {
|
||||
drawtype = "nodebox",
|
||||
description = "Tapestry Top",
|
||||
description = "Tapestry Top",
|
||||
tiles = {"default_wood.png"},
|
||||
sunlight_propagates = true,
|
||||
groups = {flammable=3,oddly_breakable_by_hand=1},
|
||||
groups = {flammable=3,oddly_breakable_by_hand=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.600000,-0.500000,0.375000,0.600000,-0.375000,0.500000},
|
||||
{-0.6,-0.5,0.375,0.6,-0.375,0.5},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.600000,-0.500000,0.375000,0.600000,-0.375000,0.500000},
|
||||
{-0.6,-0.5,0.375,0.6,-0.375,0.5},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -30,56 +30,60 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
tapestry.colours = {
|
||||
{"white", "White", "white"},
|
||||
{"grey", "Grey", "grey"},
|
||||
{"black", "Black", "black"},
|
||||
{"red", "Red", "red"},
|
||||
{"yellow", "Yellow", "yellow"},
|
||||
{"green", "Green", "green"},
|
||||
{"cyan", "Cyan", "cyan"},
|
||||
{"blue", "Blue", "blue"},
|
||||
{"magenta", "Magenta", "magenta"},
|
||||
{"orange", "Orange", "orange"},
|
||||
{"violet", "Violet", "violet"},
|
||||
{"dark_grey", "Dark Grey", "dark_grey"},
|
||||
{"dark_green", "Dark Green", "dark_green"},
|
||||
{"pink", "Pink", "pink"},
|
||||
{"brown", "Brown", "brown"},
|
||||
{"white", "White", "white", "#FFFFFF"},
|
||||
{"grey", "Grey", "grey", "#4B4B4B"},
|
||||
{"black", "Black", "black", "#1F1F1F"},
|
||||
{"red", "Red", "red", "#B21414"},
|
||||
{"yellow", "Yellow", "yellow", "#FFD011"},
|
||||
{"green", "Green", "green", "#43A91C"},
|
||||
{"cyan", "Cyan", "cyan", "#00737B"},
|
||||
{"blue", "Blue", "blue", "#003A7E"},
|
||||
{"magenta", "Magenta", "magenta", "#DD0487"},
|
||||
{"orange", "Orange", "orange", "#D55014"},
|
||||
{"violet", "Violet", "violet", "#5D01AC"},
|
||||
{"dark_grey", "Dark Grey", "dark_grey", "#3A3A3A"},
|
||||
{"dark_green", "Dark Green", "dark_green", "#206400"},
|
||||
{"pink", "Pink", "pink", "#FF8383"},
|
||||
{"brown", "Brown", "brown", "#6D3800"},
|
||||
}
|
||||
|
||||
for _, row in ipairs(tapestry.colours) do
|
||||
local name = row[1]
|
||||
local desc = row[2]
|
||||
local craft_color_group = row[3]
|
||||
local defcolor = row[4]
|
||||
-- Node Definition
|
||||
minetest.register_node("castle:tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry",
|
||||
tiles = {"wool_"..name..".png"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3,not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.312500,-0.500000,0.437500,-0.187500,-0.375000,0.500000},
|
||||
{0.187500,-0.500000,0.437500,0.312500,-0.375000,0.500000},
|
||||
{-0.375000,-0.375000,0.437500,-0.125000,-0.250000,0.500000},
|
||||
{0.125000,-0.375000,0.437500,0.375000,-0.250000,0.500000},
|
||||
{-0.437500,-0.250000,0.437500,-0.062500,-0.125000,0.500000},
|
||||
{0.062500,-0.250000,0.437500,0.437500,-0.125000,0.500000},
|
||||
{-0.500000,-0.125000,0.437500,0.000000,0.000000,0.500000},
|
||||
{0.000000,-0.125000,0.437500,0.500000,0.000000,0.500000},
|
||||
{-0.500000,0.000000,0.437500,0.500000,1.500000,0.500000},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.500000,-0.500000,0.437500,0.500000,1.500000,0.500000},
|
||||
},
|
||||
},
|
||||
minetest.register_node("castle:tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry",
|
||||
--uses default wool textures for tapestry material
|
||||
tiles = {"wool_"..name..".png^[transformR90"},
|
||||
--uses custom texture for tapestry material
|
||||
--tiles = {"castle_tapestry_overlay.png^[colorize:" .. defcolor ..":205"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.3125,-0.5,0.4375,-0.1875,-0.375,0.5},
|
||||
{0.1875,-0.5,0.4375,0.3125,-0.375,0.5},
|
||||
{-0.375,-0.375,0.4375,-0.125,-0.25,0.5},
|
||||
{0.125,-0.375,0.4375,0.375,-0.25,0.5},
|
||||
{-0.4375,-0.25,0.4375,-0.0625,-0.125,0.5},
|
||||
{0.0625,-0.25,0.4375,0.4375,-0.125,0.5},
|
||||
{-0.5,-0.125,0.4375,0.0,0.0,0.5},
|
||||
{0.0,-0.125,0.4375,0.5,0.0,0.5},
|
||||
{-0.5,0.0,0.4375,0.5,1.5,0.5},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5,-0.5,0.4375,0.5,1.5,0.5},
|
||||
},
|
||||
},
|
||||
})
|
||||
if craft_color_group then
|
||||
-- Crafting from wool and a stick
|
||||
@ -92,40 +96,43 @@ for _, row in ipairs(tapestry.colours) do
|
||||
end
|
||||
|
||||
for _, row in ipairs(tapestry.colours) do
|
||||
local name = row[1]
|
||||
local desc = row[2]
|
||||
local craft_color_group = row[3]
|
||||
-- Node Definition
|
||||
minetest.register_node("castle:long_tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry (Long)",
|
||||
tiles = {"wool_"..name..".png"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3,not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.312500,-0.500000,0.437500,-0.187500,-0.375000,0.500000},
|
||||
{0.187500,-0.500000,0.437500,0.312500,-0.375000,0.500000},
|
||||
{-0.375000,-0.375000,0.437500,-0.125000,-0.250000,0.500000},
|
||||
{0.125000,-0.375000,0.437500,0.375000,-0.250000,0.500000},
|
||||
{-0.437500,-0.250000,0.437500,-0.062500,-0.125000,0.500000},
|
||||
{0.062500,-0.250000,0.437500,0.437500,-0.125000,0.500000},
|
||||
{-0.500000,-0.125000,0.437500,0.000000,0.000000,0.500000},
|
||||
{0.000000,-0.125000,0.437500,0.500000,0.000000,0.500000},
|
||||
{-0.500000,0.000000,0.437500,0.500000,2.500000,0.500000},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.500000,-0.500000,0.437500,0.500000,2.500000,0.500000},
|
||||
},
|
||||
},
|
||||
local name = row[1]
|
||||
local desc = row[2]
|
||||
local craft_color_group = row[3]
|
||||
local defcolor = row[4]
|
||||
-- Node Definition
|
||||
minetest.register_node("castle:long_tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry (Long)",
|
||||
--uses default wool textures for tapestry material
|
||||
tiles = {"wool_"..name..".png^[transformR90"},
|
||||
--uses custom texture for tapestry material
|
||||
--tiles = {"castle_tapestry_overlay.png^[colorize:" .. defcolor ..":205"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.3125,-0.5,0.4375,-0.1875,-0.375,0.5},
|
||||
{0.1875,-0.5,0.4375,0.3125,-0.375,0.5},
|
||||
{-0.375,-0.375,0.4375,-0.125,-0.25,0.5},
|
||||
{0.125,-0.375,0.4375,0.375,-0.25,0.5},
|
||||
{-0.4375,-0.25,0.4375,-0.0625,-0.125,0.5},
|
||||
{0.0625,-0.25,0.4375,0.4375,-0.125,0.5},
|
||||
{-0.5,-0.125,0.4375,0.0,0.0,0.5},
|
||||
{0.0,-0.125,0.4375,0.5,0.0,0.5},
|
||||
{-0.5,0.0,0.4375,0.5,2.5,0.5},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5,-0.5,0.4375,0.5,2.5,0.5},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if craft_color_group then
|
||||
-- Crafting from normal tapestry and wool
|
||||
minetest.register_craft({
|
||||
@ -137,38 +144,42 @@ for _, row in ipairs(tapestry.colours) do
|
||||
end
|
||||
|
||||
for _, row in ipairs(tapestry.colours) do
|
||||
local name = row[1]
|
||||
local desc = row[2]
|
||||
local craft_color_group = row[3]
|
||||
-- Node Definition
|
||||
minetest.register_node("castle:very_long_tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry (Very Long)",
|
||||
tiles = {"wool_"..name..".png"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3,not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.312500,-0.500000,0.437500,-0.187500,-0.375000,0.500000},
|
||||
{0.187500,-0.500000,0.437500,0.312500,-0.375000,0.500000},
|
||||
{-0.375000,-0.375000,0.437500,-0.125000,-0.250000,0.500000},
|
||||
{0.125000,-0.375000,0.437500,0.375000,-0.250000,0.500000},
|
||||
{-0.437500,-0.250000,0.437500,-0.062500,-0.125000,0.500000},
|
||||
{0.062500,-0.250000,0.437500,0.437500,-0.125000,0.500000},
|
||||
{-0.500000,-0.125000,0.437500,0.000000,0.000000,0.500000},
|
||||
{0.000000,-0.125000,0.437500,0.500000,0.000000,0.500000},
|
||||
{-0.500000,0.000000,0.437500,0.500000,3.500000,0.500000},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.500000,-0.500000,0.437500,0.500000,3.500000,0.500000},
|
||||
},
|
||||
},
|
||||
local name = row[1]
|
||||
local desc = row[2]
|
||||
local craft_color_group = row[3]
|
||||
local defcolor = row[4]
|
||||
-- Node Definition
|
||||
minetest.register_node("castle:very_long_tapestry_"..name, {
|
||||
drawtype = "nodebox",
|
||||
description = desc.." Tapestry (Very Long)",
|
||||
--uses default wool textures for tapestry material
|
||||
tiles = {"wool_"..name..".png^[transformR90"},
|
||||
--uses custom texture for tapestry material
|
||||
--tiles = {"castle_tapestry_overlay.png^[colorize:" .. defcolor ..":205"},
|
||||
groups = {oddly_breakable_by_hand=3,flammable=3},
|
||||
sounds = default.node_sound_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.3125,-0.5,0.4375,-0.1875,-0.375,0.5},
|
||||
{0.1875,-0.5,0.4375,0.3125,-0.375,0.5},
|
||||
{-0.375,-0.375,0.4375,-0.125,-0.25,0.5},
|
||||
{0.125,-0.375,0.4375,0.375,-0.25,0.5},
|
||||
{-0.4375,-0.25,0.4375,-0.0625,-0.125,0.5},
|
||||
{0.0625,-0.25,0.4375,0.4375,-0.125,0.5},
|
||||
{-0.5,-0.125,0.4375,0.0,0.0,0.5},
|
||||
{0.0,-0.125,0.4375,0.5,0.0,0.5},
|
||||
{-0.5,0.0,0.4375,0.5,3.5,0.5},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5,-0.5,0.4375,0.5,3.5,0.5},
|
||||
},
|
||||
},
|
||||
})
|
||||
if craft_color_group then
|
||||
-- Crafting from long tapestry and wool
|
||||
@ -179,4 +190,3 @@ for _, row in ipairs(tapestry.colours) do
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,21 +1,38 @@
|
||||
--------------------------------------------
|
||||
|
||||
All textures based on
|
||||
original textures by: ???
|
||||
License Textures: Stuart Jones - WTFPL
|
||||
-castle_crossbow_bolt_inv.png
|
||||
-castle_crossbow_bolt_uv.png
|
||||
-castle_crossbow_hit.png
|
||||
|
||||
License Textures: ???
|
||||
Licence Models: Stuart Jones - CC-BY-SA 3.0
|
||||
-castle_crossbow_bolt.b3d
|
||||
-castle_crossbow_bolt.blend
|
||||
|
||||
--------------------------------------------
|
||||
|
||||
textures based on Castle mod
|
||||
original textures by Philipner ???
|
||||
|
||||
License Textures: CC-BY-SA 3.0 ???
|
||||
|
||||
--------------------------------------------
|
||||
|
||||
License Textures: Napiophelios - CC-BY-SA 3.0
|
||||
|
||||
-castle_battleaxe.png
|
||||
-castle_corner_stonewall1.png
|
||||
-castle_corner_stonewall2.png
|
||||
-castle_crate.png
|
||||
-castle_crate_top.png
|
||||
-castle_crossbow_bolt_inv.png
|
||||
-castle_crossbow_hit.png
|
||||
-castle_crossbow_inv.png
|
||||
-castle_crossbow_loaded.png
|
||||
-castle_door_jail.png
|
||||
-castle_door_oak.png
|
||||
-castle_dungeon_stone.png
|
||||
-castle_grey.png
|
||||
-castle_hide.png
|
||||
-castle_ironbound_chest_back.png
|
||||
-castle_ironbound_chest_front.png
|
||||
@ -24,6 +41,8 @@ License Textures: Napiophelios - CC-BY-SA 3.0
|
||||
-castle_jail_door_inv.png
|
||||
-castle_jailbars.png
|
||||
-castle_oak_door_inv.png
|
||||
-castle_orb_day_weild.png
|
||||
-castle_orb_night_weild.png
|
||||
-castle_pavement_brick.png
|
||||
-castle_ropebox_side_1.png
|
||||
-castle_ropebox_side_2.png
|
||||
@ -38,6 +57,7 @@ License Textures: Napiophelios - CC-BY-SA 3.0
|
||||
-castle_shield_side_2.png
|
||||
-castle_shield_side_3.png
|
||||
-castle_slate.png
|
||||
-castle_space.png
|
||||
-castle_steel.png
|
||||
-castle_stonewall.png
|
||||
-castle_straw_bale.png
|
||||
|
BIN
castle/textures/castle_crossbow_bolt_inv.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
castle/textures/castle_crossbow_hit.png
Normal file
After Width: | Height: | Size: 516 B |
BIN
castle/textures/castle_crossbow_inv.png
Normal file
After Width: | Height: | Size: 280 B |
BIN
castle/textures/castle_crossbow_loaded.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
castle/textures/castle_orb_day.png
Normal file
After Width: | Height: | Size: 112 B |
BIN
castle/textures/castle_orb_day_weild.png
Normal file
After Width: | Height: | Size: 185 B |
BIN
castle/textures/castle_orb_night.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
castle/textures/castle_orb_night_weild.png
Normal file
After Width: | Height: | Size: 184 B |
BIN
castle/textures/castle_tapestry_overlay.png
Normal file
After Width: | Height: | Size: 477 B |
@ -13,6 +13,7 @@ minetest.register_node("castle:anvil",{
|
||||
description = "Anvil",
|
||||
tiles = {"castle_steel.png"},
|
||||
groups = {cracky=2,falling_node=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
@ -42,6 +43,7 @@ minetest.register_node("castle:workbench",{
|
||||
paramtype2 = "facedir",
|
||||
paramtype = "light",
|
||||
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drawtype = "normal",
|
||||
on_construct = function ( pos )
|
||||
local meta = minetest.get_meta( pos )
|
||||
@ -139,7 +141,7 @@ minetest.register_abm( {
|
||||
action = function ( pos, node )
|
||||
local meta = minetest.get_meta( pos )
|
||||
local inv = meta:get_inventory()
|
||||
local cresult, newinput, needed
|
||||
local result, newinput, needed
|
||||
if not inv:is_empty( 'src' ) then
|
||||
-- Check for a valid recipe and sufficient resources to craft it
|
||||
needed, newinput, result = get_recipe( inv )
|
||||
@ -158,7 +160,6 @@ minetest.register_abm( {
|
||||
end
|
||||
} )
|
||||
|
||||
|
||||
local function has_locked_chest_privilege(meta, player)
|
||||
if player:get_player_name() ~= meta:get_string("owner") then
|
||||
return false
|
||||
@ -166,7 +167,6 @@ local function has_locked_chest_privilege(meta, player)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "castle:workbench",
|
||||
recipe = {
|
||||
@ -182,6 +182,7 @@ minetest.register_node("castle:dungeon_stone", {
|
||||
tiles = {"castle_dungeon_stone.png"},
|
||||
groups = {cracky=2},
|
||||
paramtype = "light",
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -204,6 +205,7 @@ minetest.register_node("castle:crate", {
|
||||
drawtype = "normal",
|
||||
tiles = {"castle_crate_top.png","castle_crate_top.png","castle_crate.png","castle_crate.png","castle_crate.png","castle_crate.png"},
|
||||
groups = {choppy=3},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype = "light",
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
@ -237,13 +239,6 @@ minetest.register_node("castle:crate", {
|
||||
end,
|
||||
})
|
||||
|
||||
local function has_locked_chest_privilege(meta, player)
|
||||
if player:get_player_name() ~= meta:get_string("owner") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "castle:crate",
|
||||
recipe = {
|
||||
@ -257,6 +252,7 @@ minetest.register_node("castle:bound_straw", {
|
||||
drawtype = "normal",
|
||||
tiles = {"castle_straw_bale.png"},
|
||||
groups = {choppy=4, flammable=1, oddly_breakable_by_hand=3},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
paramtype = "light",
|
||||
})
|
||||
|
||||
@ -273,6 +269,7 @@ minetest.register_node("castle:pavement_brick", {
|
||||
tiles = {"castle_pavement_brick.png"},
|
||||
groups = {cracky=2},
|
||||
paramtype = "light",
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -290,6 +287,7 @@ minetest.register_node("castle:light",{
|
||||
light_source = 14,
|
||||
tiles = {"castle_street_light.png"},
|
||||
groups = {cracky=2},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
paramtype = "light",
|
||||
})
|
||||
|
||||
@ -302,3 +300,37 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
if minetest.get_modpath("moreblocks") then
|
||||
stairsplus:register_all("castle", "dungeon_stone", "castle:dungeon_stone", {
|
||||
description = "Dungeon Stone",
|
||||
tiles = {"castle_dungeon_stone.png"},
|
||||
groups = {cracky=2, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
stairsplus:register_all("castle", "pavement_brick", "castle:pavement_brick", {
|
||||
description = "Pavement Brick",
|
||||
tiles = {"castle_pavement_brick.png"},
|
||||
groups = {cracky=2, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
else
|
||||
stairs.register_stair_and_slab("dungeon_stone", "castle:dungeon_stone",
|
||||
{cracky=2},
|
||||
{"castle_dungeon_stone.png"},
|
||||
"Dungeon Stone Stair",
|
||||
"Dungeon Stone Slab",
|
||||
default.node_sound_stone_defaults()
|
||||
)
|
||||
|
||||
stairs.register_stair_and_slab("pavement_brick", "castle:pavement_brick",
|
||||
{cracky=2},
|
||||
{"castle_pavement_brick.png"},
|
||||
"Castle Pavement Stair",
|
||||
"Castle Pavement Slab",
|
||||
default.node_sound_stone_defaults()
|
||||
)
|
||||
end
|
||||
|
@ -23,7 +23,8 @@
|
||||
-- Version 0.6
|
||||
|
||||
-- Changelog:
|
||||
-- 28.09.15 Added support for cblocks: https://forum.minetest.net/viewtopic.php?f=9&t=13303&view=unread#p192497
|
||||
-- 22.04.16 Added support for myfences: https://forum.minetest.net/viewtopic.php?f=9&t=14275
|
||||
-- 28.09.15 Added support for cblocks: https://forum.minetest.net/viewtopic.php?f=9&t=13303
|
||||
-- 23.05.15 As all dyes can be crafted into other dyes, only white dye is consumed - provided the
|
||||
-- other dyes needed for the crafting chain are stored.
|
||||
-- 22.05.15 Added support for new homedecor meshnodes.
|
||||
@ -393,6 +394,23 @@ colormachine.data[ 'mymulch_' ] = {
|
||||
p=1};
|
||||
|
||||
|
||||
local myfences_names = {'corner_post', 'garden', 'garden_corner', 'picket', 'picket_corner',
|
||||
'picketb', 'picketb_corner', 'privacy', 'privacy_corner'};
|
||||
for i,v in ipairs( myfences_names ) do
|
||||
colormachine.data[ v..'_' ] = {
|
||||
nr= 51.0 + 1/100*i,
|
||||
modname='myfences',
|
||||
shades={1,0,1,0,0,0,1,0},
|
||||
grey_shades={1,1,1,1,1},
|
||||
u=0,
|
||||
descr="myfe"..tostring(i),
|
||||
block="myfences:"..v,
|
||||
add=v..'_',
|
||||
composed=1,
|
||||
p=1};
|
||||
end
|
||||
myfences_names = nil;
|
||||
|
||||
|
||||
colormachine.ordered = {}
|
||||
|
||||
|
@ -80,13 +80,13 @@ function homedecor.handle_inventory(name, def, original_def)
|
||||
))
|
||||
end
|
||||
def.on_metadata_inventory_put = def.on_metadata_inventory_put or function(pos, listname, index, stack, player)
|
||||
minetest.log("action", S("%s moves stuff to %s at %s"):format(
|
||||
player:get_player_name(), name, minetest.pos_to_string(pos)
|
||||
minetest.log("action", S("%s moves %s to %s at %s"):format(
|
||||
player:get_player_name(), stack:get_name(), name, minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
||||
def.on_metadata_inventory_take = def.on_metadata_inventory_take or function(pos, listname, index, stack, player)
|
||||
minetest.log("action", S("%s takes stuff from %s at %s"):format(
|
||||
player:get_player_name(), name, minetest.pos_to_string(pos)
|
||||
minetest.log("action", S("%s takes %s from %s at %s"):format(
|
||||
player:get_player_name(), stack:get_name(), name, minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
||||
|
||||
|
@ -43,7 +43,7 @@ minetest.register_chatcommand("hp", {
|
||||
})
|
||||
|
||||
local function initialize_data(meta)
|
||||
local commands = meta:get_string("commands")
|
||||
local commands = minetest.formspec_escape(meta:get_string("commands"))
|
||||
meta:set_string("formspec",
|
||||
"invsize[9,5;]" ..
|
||||
"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" ..
|
||||
|
@ -16,15 +16,21 @@ minetest.override_item("default:mese", {
|
||||
}}
|
||||
})
|
||||
|
||||
minetest.register_node("mesecons_extrawires:mese_powered", {
|
||||
tiles = {minetest.registered_nodes["default:mese"].tiles[1].."^[brighten"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
-- Copy node definition of powered mese from normal mese
|
||||
-- and brighten texture tiles to indicate mese is powered
|
||||
local powered_def = mesecon.mergetable(minetest.registered_nodes["default:mese"], {
|
||||
drop = "default:mese",
|
||||
light_source = 5,
|
||||
mesecons = {conductor = {
|
||||
state = mesecon.state.on,
|
||||
offstate = "default:mese",
|
||||
rules = mesewire_rules
|
||||
}},
|
||||
drop = "default:mese"
|
||||
groups = {cracky = 1, not_in_creative_inventory = 1}
|
||||
})
|
||||
|
||||
for i, v in pairs(powered_def.tiles) do
|
||||
powered_def.tiles[i] = v .. "^[brighten"
|
||||
end
|
||||
|
||||
minetest.register_node("mesecons_extrawires:mese_powered", powered_def)
|
||||
|
@ -229,23 +229,35 @@ end
|
||||
|
||||
local function remove_functions(x)
|
||||
local tp = type(x)
|
||||
if tp == "table" then
|
||||
if tp == "function" then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Make sure to not serialize the same table multiple times, otherwise
|
||||
-- writing mem.test = mem in the LuaController will lead to infinite recursion
|
||||
local seen = {}
|
||||
|
||||
local function rfuncs(x)
|
||||
if seen[x] then return end
|
||||
seen[x] = true
|
||||
if type(x) ~= "table" then return end
|
||||
|
||||
for key, value in pairs(x) do
|
||||
local key_t, val_t = type(key), type(value)
|
||||
if key_t == "function" or val_t == "function" then
|
||||
if type(key) == "function" or type(value) == "function" then
|
||||
x[key] = nil
|
||||
else
|
||||
if key_t == "table" then
|
||||
remove_functions(key)
|
||||
if type(key) == "table" then
|
||||
rfuncs(key)
|
||||
end
|
||||
if val_t == "table" then
|
||||
remove_functions(value)
|
||||
if type(value) == "table" then
|
||||
rfuncs(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif tp == "function" then
|
||||
return nil
|
||||
end
|
||||
|
||||
rfuncs(x)
|
||||
|
||||
return x
|
||||
end
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
default
|
||||
mesecons?
|
||||
mesecons_mvps?
|
||||
digilines?
|
||||
|
@ -12,14 +12,30 @@ end
|
||||
|
||||
local function set_filter_formspec(data, meta)
|
||||
local itemname = data.wise_desc.." Filter-Injector"
|
||||
local exmatch_button = ""
|
||||
if data.stackwise then
|
||||
exmatch_button =
|
||||
fs_helpers.cycling_button(meta, "button[4,3.5;4,1", "exmatch_mode",
|
||||
|
||||
local formspec
|
||||
if data.digiline then
|
||||
formspec = "size[8,2.7]"..
|
||||
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
|
||||
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
|
||||
"field[0.3,1.5;8.0,1;channel;Channel;${channel}]"..
|
||||
fs_helpers.cycling_button(meta, "button[0,2;4,1", "slotseq_mode",
|
||||
{"Sequence slots by Priority",
|
||||
"Sequence slots Randomly",
|
||||
"Sequence slots by Rotation"})..
|
||||
fs_helpers.cycling_button(meta, "button[4,2;4,1", "exmatch_mode",
|
||||
{"Exact match - off",
|
||||
"Exact match - on "})
|
||||
end
|
||||
local formspec = "size[8,8.5]"..
|
||||
else
|
||||
local exmatch_button = ""
|
||||
if data.stackwise then
|
||||
exmatch_button =
|
||||
fs_helpers.cycling_button(meta, "button[4,3.5;4,1", "exmatch_mode",
|
||||
{"Exact match - off",
|
||||
"Exact match - on "})
|
||||
end
|
||||
|
||||
formspec = "size[8,8.5]"..
|
||||
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
|
||||
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
|
||||
"label[0,1;Prefer item types:]"..
|
||||
@ -30,6 +46,7 @@ local function set_filter_formspec(data, meta)
|
||||
"Sequence slots by Rotation"})..
|
||||
exmatch_button..
|
||||
"list[current_player;main;0,4.5;8,4;]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
||||
@ -115,7 +132,7 @@ local function grabAndFire(data,slotseq_mode,exmatch_mode,filtmeta,frominv,fromi
|
||||
return false
|
||||
end
|
||||
|
||||
local function punch_filter(data, filtpos, filtnode)
|
||||
local function punch_filter(data, filtpos, filtnode, msg)
|
||||
local filtmeta = minetest.get_meta(filtpos)
|
||||
local filtinv = filtmeta:get_inventory()
|
||||
local owner = filtmeta:get_string("owner")
|
||||
@ -131,15 +148,103 @@ local function punch_filter(data, filtpos, filtnode)
|
||||
if not fromdef then return end
|
||||
local fromtube = fromdef.tube
|
||||
if not (fromtube and fromtube.input_inventory) then return end
|
||||
|
||||
local slotseq_mode
|
||||
local exact_match
|
||||
|
||||
local filters = {}
|
||||
for _, filterstack in ipairs(filtinv:get_list("main")) do
|
||||
local filtername = filterstack:get_name()
|
||||
local filtercount = filterstack:get_count()
|
||||
if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end
|
||||
if data.digiline then
|
||||
local t_msg = type(msg)
|
||||
if t_msg == "table" then
|
||||
local slotseq = msg.slotseq
|
||||
local t_slotseq = type(slotseq)
|
||||
if t_slotseq == "number" and slotseq >= 0 and slotseq <= 2 then
|
||||
slotseq_mode = slotseq
|
||||
elseif t_slotseq == "string" then
|
||||
slotseq = string.lower(slotseq)
|
||||
if slotseq == "priority" then
|
||||
slotseq_mode = 0
|
||||
elseif slotseq == "random" then
|
||||
slotseq_mode = 1
|
||||
elseif slotseq == "rotation" then
|
||||
slotseq_mode = 2
|
||||
end
|
||||
end
|
||||
|
||||
local exmatch = msg.exmatch
|
||||
local t_exmatch = type(exmatch)
|
||||
if t_exmatch == "number" and exmatch >= 0 and exmatch <= 1 then
|
||||
exact_match = exmatch
|
||||
elseif t_exmatch == "boolean" then
|
||||
exact_match = exmatch and 1 or 0
|
||||
end
|
||||
|
||||
local slotseq_index = msg.slotseq_index
|
||||
if type(slotseq_index) == "number" then
|
||||
-- This should allow any valid index, but I'm not completely sure what
|
||||
-- constitutes a valid index, so I'm only allowing resetting it to 1.
|
||||
if slotseq_index == 1 then
|
||||
filtmeta:set_int("slotseq_index", slotseq_index)
|
||||
set_filter_infotext(data, filtmeta)
|
||||
end
|
||||
end
|
||||
|
||||
if slotseq_mode ~= nil then
|
||||
filtmeta:set_int("slotseq_mode", slotseq_mode)
|
||||
end
|
||||
|
||||
if exact_match ~= nil then
|
||||
filtmeta:set_int("exmatch_mode", exact_match)
|
||||
end
|
||||
|
||||
if slotseq_mode ~= nil or exact_match ~= nil then
|
||||
set_filter_formspec(data, filtmeta)
|
||||
end
|
||||
|
||||
if msg.nofire then
|
||||
return
|
||||
end
|
||||
|
||||
if type(msg.name) == "string" then
|
||||
table.insert(filters, {name = msg.name, count = tonumber(msg.count) or 1})
|
||||
else
|
||||
for _, filter in ipairs(msg) do
|
||||
local t_filter = type(filter)
|
||||
if t_filter == "table" then
|
||||
if type(filter.name) == "string" then
|
||||
table.insert(filters, {name = filter.name, count = tonumber(filter.count) or 1})
|
||||
end
|
||||
elseif t_filter == "string" then
|
||||
local filterstack = ItemStack(filter)
|
||||
local filtername = filterstack:get_name()
|
||||
local filtercount = filterstack:get_count()
|
||||
if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif t_msg == "string" then
|
||||
local filterstack = ItemStack(msg)
|
||||
local filtername = filterstack:get_name()
|
||||
local filtercount = filterstack:get_count()
|
||||
if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end
|
||||
end
|
||||
else
|
||||
for _, filterstack in ipairs(filtinv:get_list("main")) do
|
||||
local filtername = filterstack:get_name()
|
||||
local filtercount = filterstack:get_count()
|
||||
if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end
|
||||
end
|
||||
end
|
||||
if #filters == 0 then table.insert(filters, "") end
|
||||
local slotseq_mode = filtmeta:get_int("slotseq_mode")
|
||||
local exact_match = filtmeta:get_int("exmatch_mode")
|
||||
|
||||
if slotseq_mode == nil then
|
||||
slotseq_mode = filtmeta:get_int("slotseq_mode")
|
||||
end
|
||||
|
||||
if exact_match == nil then
|
||||
exact_match = filtmeta:get_int("exmatch_mode")
|
||||
end
|
||||
|
||||
local frommeta = minetest.get_meta(frompos)
|
||||
local frominv = frommeta:get_inventory()
|
||||
if fromtube.before_filter then fromtube.before_filter(frompos) end
|
||||
@ -167,8 +272,14 @@ for _, data in ipairs({
|
||||
wise_desc = "Stackwise",
|
||||
stackwise = true,
|
||||
},
|
||||
{ -- register even if no digilines
|
||||
name = "digiline_filter",
|
||||
wise_desc = "Digiline",
|
||||
stackwise = true,
|
||||
digiline = true,
|
||||
},
|
||||
}) do
|
||||
minetest.register_node("pipeworks:"..data.name, {
|
||||
local node = {
|
||||
description = data.wise_desc.." Filter-Injector",
|
||||
tiles = {
|
||||
"pipeworks_"..data.name.."_top.png",
|
||||
@ -194,14 +305,6 @@ for _, data in ipairs({
|
||||
pipeworks.after_place(pos)
|
||||
end,
|
||||
after_dig_node = pipeworks.after_dig,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("slotseq_index", 1)
|
||||
set_filter_formspec(data, meta)
|
||||
set_filter_infotext(data, meta)
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if not pipeworks.may_configure(pos, player) then return 0 end
|
||||
return stack:get_count()
|
||||
@ -219,18 +322,63 @@ for _, data in ipairs({
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main")
|
||||
end,
|
||||
mesecons = {
|
||||
tube = {connect_sides = {right = 1}},
|
||||
}
|
||||
|
||||
if data.digiline then
|
||||
node.groups.mesecon = nil
|
||||
if not minetest.get_modpath("digilines") then
|
||||
node.groups.not_in_creative_inventory = 1
|
||||
end
|
||||
|
||||
node.on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
|
||||
if fields.channel then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
--meta:set_int("slotseq_index", 1)
|
||||
set_filter_formspec(data, meta)
|
||||
set_filter_infotext(data, meta)
|
||||
end
|
||||
node.digiline = {
|
||||
effector = {
|
||||
action = function(pos, node, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local setchan = meta:get_string("channel")
|
||||
if setchan ~= channel then return end
|
||||
|
||||
punch_filter(data, pos, node, msg)
|
||||
end,
|
||||
},
|
||||
}
|
||||
else
|
||||
node.on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("slotseq_index", 1)
|
||||
set_filter_formspec(data, meta)
|
||||
set_filter_infotext(data, meta)
|
||||
end
|
||||
node.mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos, node)
|
||||
punch_filter(data, pos, node)
|
||||
end,
|
||||
},
|
||||
},
|
||||
tube = {connect_sides = {right = 1}},
|
||||
on_punch = function (pos, node, puncher)
|
||||
}
|
||||
node.on_punch = function (pos, node, puncher)
|
||||
punch_filter(data, pos, node)
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
minetest.register_node("pipeworks:"..data.name, node)
|
||||
end
|
||||
|
||||
minetest.register_craft( {
|
||||
@ -250,3 +398,14 @@ minetest.register_craft( {
|
||||
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }
|
||||
},
|
||||
})
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
minetest.register_craft( {
|
||||
output = "pipeworks:digiline_filter 2",
|
||||
recipe = {
|
||||
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" },
|
||||
{ "group:stick", "digilines:wire_std_00000000", "homedecor:plastic_sheeting" },
|
||||
{ "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }
|
||||
},
|
||||
})
|
||||
end
|
||||
|
BIN
pipeworks/textures/pipeworks_digiline_filter_input.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
pipeworks/textures/pipeworks_digiline_filter_output.png
Normal file
After Width: | Height: | Size: 217 B |
BIN
pipeworks/textures/pipeworks_digiline_filter_side.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
pipeworks/textures/pipeworks_digiline_filter_top.png
Normal file
After Width: | Height: | Size: 236 B |
@ -924,7 +924,7 @@ function signs_lib.register_fence_with_sign(fencename, fencewithsignname)
|
||||
minetest.register_node(":"..fencename, def)
|
||||
minetest.register_node(":"..fencewithsignname, def_sign)
|
||||
table.insert(signs_lib.sign_node_list, fencewithsignname)
|
||||
minetest.log("debug", S("Registered %s and %s"):format(fencename, fencewithsignname))
|
||||
minetest.log("verbose", S("Registered %s and %s"):format(fencename, fencewithsignname))
|
||||
end
|
||||
|
||||
build_char_db()
|
||||
|
@ -157,13 +157,13 @@ function technic.machine_after_dig_node(pos, oldnode, oldmetadata, player)
|
||||
if oldmetadata.inventory.upgrade1 and oldmetadata.inventory.upgrade1[1] then
|
||||
local stack = ItemStack(oldmetadata.inventory.upgrade1[1])
|
||||
if not stack:is_empty() then
|
||||
minetest.item_drop(stack, "", pos)
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
if oldmetadata.inventory.upgrade2 and oldmetadata.inventory.upgrade2[1] then
|
||||
local stack = ItemStack(oldmetadata.inventory.upgrade2[1])
|
||||
if not stack:is_empty() then
|
||||
minetest.item_drop(stack, "", pos)
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
154
xban2/gui.lua
@ -1,56 +1,118 @@
|
||||
|
||||
local FORMNAME = "xban2:main"
|
||||
local MAXLISTSIZE = 100
|
||||
|
||||
local states = { }
|
||||
|
||||
local table_insert, table_concat =
|
||||
table.insert, table.concat
|
||||
local strfind, format = string.find, string.format
|
||||
|
||||
local ESC = minetest.formspec_escape
|
||||
|
||||
local function make_fs(name)
|
||||
local state = states[name]
|
||||
if not state then return end
|
||||
local list, index, filter = state.list, state.index, state.filter
|
||||
if index > #list then
|
||||
index = #list
|
||||
end
|
||||
local fs = {
|
||||
"size[10,8]",
|
||||
"label[0.5,0.6;Filter]",
|
||||
"field[1.5,0.5;6,2;filter;;"..ESC(filter).."]",
|
||||
"button[7.5,0.5;2,1;search;Search]",
|
||||
}
|
||||
table_insert(fs,
|
||||
("textlist[0.5,2;3,5.5;player;%s;%d;0]"):
|
||||
format(table_concat(list, ","), index))
|
||||
local record_name = list[index]
|
||||
if record_name then
|
||||
local record, err = xban.get_record(record_name)
|
||||
if record then
|
||||
local reclist = { }
|
||||
for _, r in ipairs(record) do
|
||||
table_insert(reclist, ESC(r))
|
||||
local function make_list(filter)
|
||||
filter = filter or ""
|
||||
local list, n, dropped = { }, 0, false
|
||||
for k in pairs(minetest.auth_table) do
|
||||
if strfind(k, filter, 1, true) then
|
||||
if n >= MAXLISTSIZE then
|
||||
dropped = true
|
||||
break
|
||||
end
|
||||
table_insert(fs,
|
||||
("textlist[4,2;5,5.5;entry;%s;0;0]"):
|
||||
format(table_concat(reclist, ",")))
|
||||
else
|
||||
table_insert(fs,
|
||||
"textlist[4,2;5,5.5;entry;"..ESC(err)..";0]")
|
||||
n=n+1 list[n] = k
|
||||
end
|
||||
end
|
||||
return table_concat(fs)
|
||||
table.sort(list)
|
||||
return list, dropped
|
||||
end
|
||||
|
||||
local states = { }
|
||||
|
||||
local function get_state(name)
|
||||
local state = states[name]
|
||||
if not state then
|
||||
state = { index=1, filter="" }
|
||||
states[name] = state
|
||||
state.list, state.dropped = make_list()
|
||||
end
|
||||
return state
|
||||
end
|
||||
|
||||
local function get_record_simple(name)
|
||||
local e = xban.find_entry(name)
|
||||
if not e then
|
||||
return nil, ("No entry for `%s'"):format(name)
|
||||
elseif (not e.record) or (#e.record == 0) then
|
||||
return nil, ("`%s' has no ban records"):format(name)
|
||||
end
|
||||
local record = { }
|
||||
for _, rec in ipairs(e.record) do
|
||||
local msg = (os.date("%Y-%m-%d %H:%M:%S", rec.time).." | "
|
||||
..(rec.reason or "No reason given."))
|
||||
table.insert(record, msg)
|
||||
end
|
||||
return record, e.record
|
||||
end
|
||||
|
||||
local function make_fs(name)
|
||||
local state = get_state(name)
|
||||
local list, filter = state.list, state.filter
|
||||
local pli, ei = state.player_index or 1, state.entry_index or 0
|
||||
if pli > #list then
|
||||
pli = #list
|
||||
end
|
||||
local fs = {
|
||||
"size[16,12]",
|
||||
"label[0,-.1;Filter]",
|
||||
"field[1.5,0;12.8,1;filter;;"..ESC(filter).."]",
|
||||
"button[14,-.3;2,1;search;Search]",
|
||||
}
|
||||
local fsn = #fs
|
||||
fsn=fsn+1 fs[fsn] = format("textlist[0,.8;4,9.3;player;%s;%d;0]",
|
||||
table.concat(list, ","), pli)
|
||||
local record_name = list[pli]
|
||||
if record_name then
|
||||
local record, e = get_record_simple(record_name)
|
||||
if record then
|
||||
for i, r in ipairs(record) do
|
||||
record[i] = ESC(r)
|
||||
end
|
||||
fsn=fsn+1 fs[fsn] = format(
|
||||
"textlist[4.2,.8;11.7,9.3;entry;%s;%d;0]",
|
||||
table.concat(record, ","), ei)
|
||||
local rec = e[ei]
|
||||
if rec then
|
||||
fsn=fsn+1 fs[fsn] = format("label[0,10.3;%s]",
|
||||
ESC("Source: "..(rec.source or "<none>")
|
||||
.."\nTime: "..os.date("%c", rec.time)
|
||||
.."\n"..(rec.expires and
|
||||
os.date("%c", rec.expires) or "")),
|
||||
pli)
|
||||
end
|
||||
else
|
||||
fsn=fsn+1 fs[fsn] = "textlist[4.2,.8;11.7,9.3;err;"..ESC(e)..";0]"
|
||||
fsn=fsn+1 fs[fsn] = "label[0,10.3;"..ESC(e).."]"
|
||||
end
|
||||
else
|
||||
local e = "No entry matches the query."
|
||||
fsn=fsn+1 fs[fsn] = "textlist[4.2,.8;11.7,9.3;err;"..ESC(e)..";0]"
|
||||
fsn=fsn+1 fs[fsn] = "label[0,10.3;"..ESC(e).."]"
|
||||
end
|
||||
return table.concat(fs)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= FORMNAME then return end
|
||||
local name = player:get_player_name()
|
||||
local state = states[name]
|
||||
local state = get_state(name)
|
||||
if fields.player then
|
||||
local t = minetest.explode_textlist_event(fields.player)
|
||||
if (t.type == "CHG") or (t.type == "DCL") then
|
||||
state.index = t.index
|
||||
state.player_index = t.index
|
||||
minetest.show_formspec(name, FORMNAME, make_fs(name))
|
||||
end
|
||||
return
|
||||
end
|
||||
if fields.entry then
|
||||
local t = minetest.explode_textlist_event(fields.entry)
|
||||
if (t.type == "CHG") or (t.type == "DCL") then
|
||||
state.entry_index = t.index
|
||||
minetest.show_formspec(name, FORMNAME, make_fs(name))
|
||||
end
|
||||
return
|
||||
@ -58,14 +120,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if fields.search then
|
||||
local filter = fields.filter or ""
|
||||
state.filter = filter
|
||||
local list = { }
|
||||
state.list = list
|
||||
for k in pairs(minetest.auth_table) do
|
||||
if k:find(filter, 1, true) then
|
||||
table_insert(list, k)
|
||||
end
|
||||
end
|
||||
table.sort(list)
|
||||
state.list = make_list(filter)
|
||||
minetest.show_formspec(name, FORMNAME, make_fs(name))
|
||||
end
|
||||
end)
|
||||
@ -74,17 +129,6 @@ minetest.register_chatcommand("xban_gui", {
|
||||
description = "Show XBan GUI",
|
||||
params = "",
|
||||
func = function(name, params)
|
||||
local state = states[name]
|
||||
if not state then
|
||||
state = { index=1, filter="" }
|
||||
states[name] = state
|
||||
local list = { }
|
||||
state.list = list
|
||||
for k in pairs(minetest.auth_table) do
|
||||
table_insert(list, k)
|
||||
end
|
||||
table.sort(list)
|
||||
end
|
||||
minetest.show_formspec(name, FORMNAME, make_fs(name))
|
||||
end,
|
||||
})
|
||||
|