Add the initial files
|
@ -0,0 +1,22 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
|
@ -0,0 +1,215 @@
|
|||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
sdist/
|
||||
develop-eggs/
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
|
@ -0,0 +1,12 @@
|
|||
Game used for Craig's Survival Server [Craig-Survival_game]
|
||||
==========================================================
|
||||
|
||||
This is the game used by Craig's Survival Server
|
||||
|
||||
It is an edited version of minetest_game (https://github.com/minetest/minetest_game) with lots of other mods added to it.
|
||||
|
||||
For information about the server go here: https://forum.minetest.net/viewtopic.php?id=7010
|
||||
|
||||
License
|
||||
-------
|
||||
See the README.txt or LICENSE.txt for each separate mod for licence information.
|
|
@ -0,0 +1,7 @@
|
|||
## Generic ignorable patterns and files
|
||||
*~
|
||||
.*.swp
|
||||
*bak*
|
||||
tags
|
||||
*.vim
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[mod] Visible Player Armor [3d_armor]
|
||||
=====================================
|
||||
|
||||
depends: default, inventory_plus, unified_skins
|
||||
|
||||
Adds craftable armor that is visible to other players. Each armor item worn contibutes to
|
||||
a player's armor group level making them less vulnerable to weapons.
|
||||
|
||||
Armor takes damage when a player is hurt but also offers a percentage chance of healing.
|
||||
|
||||
default settings: [minetest.conf]
|
||||
|
||||
# Set number of seconds between armor updates.
|
||||
3d_armor_update_time = 1
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
local time = 0
|
||||
local update_time = tonumber(minetest.setting_get("3d_armor_update_time"))
|
||||
if not update_time then
|
||||
update_time = 1
|
||||
minetest.setting_set("3d_armor_update_time", tostring(update_time))
|
||||
end
|
||||
|
||||
armor = {
|
||||
player_hp = {},
|
||||
elements = {"head", "torso", "legs", "feet"},
|
||||
formspec = "size[8,8.5]button[0,0;2,0.5;main;Back]"
|
||||
.."list[current_player;main;0,4.5;8,4;]"
|
||||
.."list[detached:player_name_armor;armor_head;3,0;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_torso;3,1;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_legs;3,2;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_feet;3,3;1,1;]",
|
||||
}
|
||||
|
||||
armor.def = {
|
||||
state = 0,
|
||||
count = 0
|
||||
}
|
||||
|
||||
armor.set_player_armor = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_texture = uniskins.default_texture
|
||||
local armor_level = 0
|
||||
local state = 0
|
||||
local items = 0
|
||||
local textures = {}
|
||||
for _,v in ipairs(self.elements) do
|
||||
local stack = player_inv:get_stack("armor_"..v, 1)
|
||||
local level = stack:get_definition().groups["armor_"..v]
|
||||
if level then
|
||||
local item = stack:get_name()
|
||||
table.insert(textures, item:gsub("%:", "_")..".png")
|
||||
armor_level = armor_level + level
|
||||
state = state + stack:get_wear()
|
||||
items = items+1
|
||||
end
|
||||
end
|
||||
if table.getn(textures) > 0 then
|
||||
armor_texture = table.concat(textures, "^")
|
||||
end
|
||||
local armor_groups = {fleshy=100}
|
||||
if armor_level > 0 then
|
||||
armor_groups.level = math.floor(armor_level / 20)
|
||||
armor_groups.fleshy = 100 - armor_level
|
||||
end
|
||||
player:set_armor_groups(armor_groups)
|
||||
uniskins.armor[name] = armor_texture
|
||||
uniskins:update_player_visuals(player)
|
||||
armor.def[name].state = state
|
||||
armor.def[name].count = items
|
||||
end
|
||||
|
||||
armor.update_armor = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local hp = player:get_hp() or 0
|
||||
if hp == 0 or hp == self.player_hp[name] then
|
||||
return
|
||||
end
|
||||
if self.player_hp[name] > hp then
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
if not armor_inv then
|
||||
return
|
||||
end
|
||||
local heal_max = 0
|
||||
local state = 0
|
||||
local items = 0
|
||||
for _,v in ipairs(self.elements) do
|
||||
local stack = armor_inv:get_stack("armor_"..v, 1)
|
||||
if stack:get_count() > 0 then
|
||||
local use = stack:get_definition().groups["armor_use"] or 0
|
||||
local heal = stack:get_definition().groups["armor_heal"] or 0
|
||||
local item = stack:get_name()
|
||||
stack:add_wear(use)
|
||||
armor_inv:set_stack("armor_"..v, 1, stack)
|
||||
player_inv:set_stack("armor_"..v, 1, stack)
|
||||
state = state + stack:get_wear()
|
||||
items = items+1
|
||||
if stack:get_count() == 0 then
|
||||
local desc = minetest.registered_items[item].description
|
||||
if desc then
|
||||
minetest.chat_send_player(name, "Your "..desc.." got destroyed!")
|
||||
end
|
||||
self:set_player_armor(player)
|
||||
end
|
||||
heal_max = heal_max + heal
|
||||
end
|
||||
end
|
||||
armor.def[name].state = state
|
||||
armor.def[name].count = items
|
||||
if heal_max > math.random(100) then
|
||||
player:set_hp(self.player_hp[name])
|
||||
return
|
||||
end
|
||||
end
|
||||
self.player_hp[name] = hp
|
||||
end
|
||||
|
||||
-- Register Callbacks
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local name = player:get_player_name()
|
||||
if fields.armor then
|
||||
local formspec = armor.formspec:gsub("player_name", name)
|
||||
inventory_plus.set_inventory_formspec(player, formspec)
|
||||
return
|
||||
end
|
||||
for field, _ in pairs(fields) do
|
||||
if string.sub(field,0,string.len("skins_set_")) == "skins_set_" then
|
||||
minetest.after(0, function(player)
|
||||
uniskins.skin[name] = skins.skins[name]..".png"
|
||||
uniskins:update_player_visuals(player)
|
||||
end, player)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
inventory_plus.register_button(player,"armor", "Armor")
|
||||
local player_inv = player:get_inventory()
|
||||
local name = player:get_player_name()
|
||||
local armor_inv = minetest.create_detached_inventory(name.."_armor",{
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, stack)
|
||||
armor:set_player_armor(player)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, nil)
|
||||
armor:set_player_armor(player)
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
if inv:is_empty(listname) then
|
||||
return 1
|
||||
end
|
||||
return 0
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player)
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return 0
|
||||
end,
|
||||
})
|
||||
for _,v in ipairs(armor.elements) do
|
||||
local list = "armor_"..v
|
||||
player_inv:set_size(list, 1)
|
||||
armor_inv:set_size(list, 1)
|
||||
armor_inv:set_stack(list, 1, player_inv:get_stack(list, 1))
|
||||
end
|
||||
armor.player_hp[name] = 0
|
||||
armor.def[name] = {
|
||||
state = 0,
|
||||
count = 0
|
||||
}
|
||||
minetest.after(0, function(player)
|
||||
armor:set_player_armor(player)
|
||||
end, player)
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
if time > update_time then
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
armor:update_armor(player)
|
||||
end
|
||||
time = 0
|
||||
end
|
||||
end)
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
3d_armor -- Crafting Guide
|
||||
--------------------------
|
||||
|
||||
Helmets:
|
||||
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| | | |
|
||||
+---+---+---+
|
||||
|
||||
[3d_armor:helmet_wood] X = [default:wood]
|
||||
[3d_armor:helmet_steel] X = [default:steel_ingot]
|
||||
[3d_armor:helmet_bronze] X = [default:bronze_ingot]
|
||||
[3d_armor:helmet_diamond] X = [default:diamond]
|
||||
|
||||
Chestplates:
|
||||
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
|
||||
[3d_armor:chestplate_wood] X = [default:wood]
|
||||
[3d_armor:chestplate_steel] X = [default:steel_ingot]
|
||||
[3d_armor:chestplate_bronze] X = [default:bronze_ingot]
|
||||
[3d_armor:chestplate_diamond] X = [default:diamond]
|
||||
|
||||
Leggings:
|
||||
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
|
||||
[3d_armor:leggings_wood] X = [default:wood]
|
||||
[3d_armor:leggings_steel] X = [default:steel_ingot]
|
||||
[3d_armor:leggings_bronze] X = [default:bronze_ingot]
|
||||
[3d_armor:leggings_diamond] X = [default:diamond]
|
||||
|
||||
Boots:
|
||||
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
|
||||
[3d_armor:boots_wood] X = [default:wood]
|
||||
[3d_armor:boots_steel] X = [default:steel_ingot]
|
||||
[3d_armor:boots_bronze] X = [default:bronze_ingot
|
||||
[3d_armor:boots_diamond] X = [default:diamond]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
default
|
||||
inventory_plus
|
||||
unified_skins
|
|
@ -0,0 +1,168 @@
|
|||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/armor.lua")
|
||||
|
||||
-- Regisiter Head Armor
|
||||
|
||||
minetest.register_tool("3d_armor:helmet_wood", {
|
||||
description = "Wood Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_wood.png",
|
||||
groups = {armor_head=5, armor_heal=0, armor_use=2000},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:helmet_steel", {
|
||||
description = "Steel Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_steel.png",
|
||||
groups = {armor_head=10, armor_heal=0, armor_use=500},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:helmet_bronze", {
|
||||
description = "Bronze Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_bronze.png",
|
||||
groups = {armor_head=10, armor_heal=6, armor_use=250},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:helmet_diamond", {
|
||||
description = "Diamond Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_diamond.png",
|
||||
groups = {armor_head=15, armor_heal=12, armor_use=100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
-- Regisiter Torso Armor
|
||||
|
||||
minetest.register_tool("3d_armor:chestplate_wood", {
|
||||
description = "Wood Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_wood.png",
|
||||
groups = {armor_torso=10, armor_heal=0, armor_use=2000},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:chestplate_steel", {
|
||||
description = "Steel Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_steel.png",
|
||||
groups = {armor_torso=15, armor_heal=0, armor_use=500},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:chestplate_bronze", {
|
||||
description = "Bronze Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_bronze.png",
|
||||
groups = {armor_torso=15, armor_heal=6, armor_use=250},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:chestplate_diamond", {
|
||||
description = "Diamond Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_diamond.png",
|
||||
groups = {armor_torso=20, armor_heal=12, armor_use=100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
-- Regisiter Leg Armor
|
||||
|
||||
minetest.register_tool("3d_armor:leggings_wood", {
|
||||
description = "Wood Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_wood.png",
|
||||
groups = {armor_legs=5, armor_heal=0, armor_use=2000},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:leggings_steel", {
|
||||
description = "Steel Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_steel.png",
|
||||
groups = {armor_legs=15, armor_heal=0, armor_use=500},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:leggings_bronze", {
|
||||
description = "Bronze Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_bronze.png",
|
||||
groups = {armor_legs=15, armor_heal=6, armor_use=250},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:leggings_diamond", {
|
||||
description = "Diamond Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_diamond.png",
|
||||
groups = {armor_legs=20, armor_heal=12, armor_use=100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
-- Regisiter Boots
|
||||
|
||||
minetest.register_tool("3d_armor:boots_wood", {
|
||||
description = "Wood Boots",
|
||||
inventory_image = "3d_armor_inv_boots_wood.png",
|
||||
groups = {armor_feet=5, armor_heal=0, armor_use=2000},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:boots_steel", {
|
||||
description = "Steel Boots",
|
||||
inventory_image = "3d_armor_inv_boots_steel.png",
|
||||
groups = {armor_feet=10, armor_heal=0, armor_use=500},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:boots_bronze", {
|
||||
description = "Bronze Boots",
|
||||
inventory_image = "3d_armor_inv_boots_bronze.png",
|
||||
groups = {armor_feet=10, armor_heal=6, armor_use=250},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:boots_diamond", {
|
||||
description = "Diamond Boots",
|
||||
inventory_image = "3d_armor_inv_boots_diamond.png",
|
||||
groups = {armor_feet=15, armor_heal=12, armor_use=100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
-- Register Craft Recipies
|
||||
|
||||
local craft_ingreds = {
|
||||
wood = "default:wood",
|
||||
steel = "default:steel_ingot",
|
||||
bronze = "default:bronze_ingot",
|
||||
diamond = "default:diamond",
|
||||
}
|
||||
|
||||
for k, v in pairs(craft_ingreds) do
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:helmet_"..k,
|
||||
recipe = {
|
||||
{v, v, v},
|
||||
{v, "", v},
|
||||
{"", "", ""},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:chestplate_"..k,
|
||||
recipe = {
|
||||
{v, "", v},
|
||||
{v, v, v},
|
||||
{v, v, v},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:leggings_"..k,
|
||||
recipe = {
|
||||
{v, v, v},
|
||||
{v, "", v},
|
||||
{v, "", v},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:boots_"..k,
|
||||
recipe = {
|
||||
{v, "", v},
|
||||
{v, "", v},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
|
After Width: | Height: | Size: 632 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 609 B |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 933 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 858 B |
After Width: | Height: | Size: 863 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 246 B |
After Width: | Height: | Size: 247 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 244 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 239 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 237 B |
After Width: | Height: | Size: 639 B |
After Width: | Height: | Size: 622 B |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 577 B |
After Width: | Height: | Size: 723 B |
|
@ -0,0 +1,11 @@
|
|||
3D Armor - Visible Player Armor
|
||||
===============================
|
||||
|
||||
Default Item Textures (C) Cisoun - WTFPL
|
||||
|
||||
Armor Textures: Copyright (C) 2013 Ryan Jones - CC-BY-SA
|
||||
|
||||
Source Code: Copyright (C) 2013 Stuart Jones - LGPL
|
||||
|
||||
Special credit to Jordach and MirceaKitsune for providing the default 3d character model.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
Modpack - 3d Armor
|
||||
==================
|
||||
|
||||
[mod] Unified Skins [unified_skins]
|
||||
-----------------------------------
|
||||
|
||||
depends: default
|
||||
|
||||
A 3d character model re-texturing api used as the framework for this modpack.
|
||||
|
||||
Compatible with player skins mod [skins] by Zeg9 and Player Textures [player_textures] by sdzen.
|
||||
|
||||
Note: Currently only supports 64x32px player skins.
|
||||
|
||||
[mod] Visible Wielded Items [wieldview]
|
||||
---------------------------------------
|
||||
|
||||
depends: unified_skins
|
||||
|
||||
Makes hand wielded items visible to other players.
|
||||
|
||||
Note: Currently only supports 16x16px texture packs, sorry!
|
||||
|
||||
[mod] Visible Player Armor [3d_armor]
|
||||
-------------------------------------
|
||||
|
||||
depends: unified_skins, inventory_plus
|
||||
|
||||
Adds craftable armor that is visible to other players. Each armor item worn contributes to
|
||||
a player's armor group level making them less vulnerable to weapons.
|
||||
|
||||
Armor takes damage when a player is hurt, however, many armor items offer a 'stackable'
|
||||
percentage chance of restoring the lost health points.
|
||||
|
||||
[mod] Shields [shields]
|
||||
-------------------------------------
|
||||
|
||||
depends: 3d_armor
|
||||
|
||||
Originally a part of 3d_armor, shields have been re-included as an optional extra.
|
||||
If you do not want shields then simply remove the shields folder from the modpack.
|
|
@ -0,0 +1,6 @@
|
|||
A 3d character model re-texturing api used as the framework for this modpack.
|
||||
|
||||
depends: 3d_armor
|
||||
|
||||
Originally a part of 3d_armor, shields have been re-included as an optional extra.
|
||||
If you do not what shields then simply remove the shields folder from the modpack.
|
|
@ -0,0 +1,17 @@
|
|||
Shields -- Crafting Guide
|
||||
--------------------------
|
||||
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| | X | |
|
||||
+---+---+---+
|
||||
|
||||
[shields:shield_wood] X = [default:wood]
|
||||
[shields:shield_steel] X = [default:steel_ingot]
|
||||
[shields:shield_bronze] X = [default:bronze_ingot]
|
||||
[shields:shield_diamond] X = [default:diamond]
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
default
|
||||
inventory_plus
|
||||
3d_armor
|
|
@ -0,0 +1,61 @@
|
|||
-- Regisiter Shields
|
||||
|
||||
minetest.register_tool("shields:shield_wood", {
|
||||
description = "Wooden Shield",
|
||||
inventory_image = "shields_inv_shield_wood.png",
|
||||
groups = {armor_shield=5, armor_heal=0, armor_use=2000},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("shields:shield_steel", {
|
||||
description = "Steel Shield",
|
||||
inventory_image = "shields_inv_shield_steel.png",
|
||||
groups = {armor_shield=10, armor_heal=0, armor_use=500},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("shields:shield_bronze", {
|
||||
description = "Bronze Shield",
|
||||
inventory_image = "shields_inv_shield_bronze.png",
|
||||
groups = {armor_shield=10, armor_heal=6, armor_use=250},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("shields:shield_diamond", {
|
||||
description = "Diamond Shield",
|
||||
inventory_image = "shields_inv_shield_diamond.png",
|
||||
groups = {armor_shield=15, armor_heal=12, armor_use=100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
local craft_ingreds = {
|
||||
wood = "default:wood",
|
||||
steel = "default:steel_ingot",
|
||||
bronze = "default:bronze_ingot",
|
||||
diamond = "default:diamond",
|
||||
}
|
||||
|
||||
for k, v in pairs(craft_ingreds) do
|
||||
minetest.register_craft({
|
||||
output = "shields:shield_"..k,
|
||||
recipe = {
|
||||
{v, v, v},
|
||||
{v, v, v},
|
||||
{"", v, ""},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.after(0, function()
|
||||
table.insert(armor.elements, "shield")
|
||||
armor.formspec = "size[8,8.5]button[0,0;2,0.5;main;Back]"
|
||||
.."list[current_player;main;0,4.5;8,4;]"
|
||||
.."list[detached:player_name_armor;armor_head;3,0;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_torso;3,1;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_legs;3,2;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_feet;3,3;1,1;]"
|
||||
.."list[detached:player_name_armor;armor_shield;4,1;1,1;]"
|
||||
end)
|
||||
|
||||
|
After Width: | Height: | Size: 654 B |
After Width: | Height: | Size: 640 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 668 B |
After Width: | Height: | Size: 657 B |
After Width: | Height: | Size: 626 B |
|
@ -0,0 +1,7 @@
|
|||
A 3d character model re-texturing api used as the framework for this modpack.
|
||||
|
||||
depends: default
|
||||
|
||||
Compatible with player skins mod [skins] by Zeg9 and Player Textures [player_textures] by sdzen.
|
||||
|
||||
Note: Currently only 64x32px player skins.
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
uniskins = {
|
||||
skin = {},
|
||||
armor = {},
|
||||
wielditem = {},
|
||||
default_skin = "character.png",
|
||||
default_texture = "uniskins_trans.png",
|
||||
}
|
||||
|
||||
uniskins.update_player_visuals = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
player:set_properties({
|
||||
visual = "mesh",
|
||||
mesh = "uniskins_character.x",
|
||||
textures = {
|
||||
self.skin[name],
|
||||
self.armor[name],
|
||||
self.wielditem[name]
|
||||
},
|
||||
visual_size = {x=1, y=1},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
uniskins.skin[name] = uniskins.default_skin
|
||||
uniskins.armor[name] = uniskins.default_texture
|
||||
uniskins.wielditem[name] = uniskins.default_texture
|
||||
if minetest.get_modpath("player_textures") then
|
||||
local filename = minetest.get_modpath("player_textures").."/textures/player_"..name
|
||||
local f = io.open(filename..".png")
|
||||
if f then
|
||||
f:close()
|
||||
uniskins.skin[name] = "player_"..name..".png"
|
||||
end
|
||||
end
|
||||
if minetest.get_modpath("skins") then
|
||||
local skin = skins.skins[name]
|
||||
if skin and skins.get_type(skin) == skins.type.MODEL then
|
||||
uniskins.skin[name] = skin..".png"
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
After Width: | Height: | Size: 146 B |
|
@ -0,0 +1,17 @@
|
|||
[mod] visible wielded items [wieldview]
|
||||
=======================================
|
||||
|
||||
depends: default, unified_skins
|
||||
|
||||
Makes hand wielded items visible to other players. Compatible with player skins mod [skins].
|
||||
|
||||
Note: Currently only supports 16x16px texture packs, sorry!
|
||||
|
||||
default settings: [minetest.conf]
|
||||
|
||||
# Set number of seconds between visible wielded item updates.
|
||||
wieldview_update_time = 2
|
||||
|
||||
# Show nodes as tiles, disabled by default
|
||||
wieldview_node_tiles = false
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
default
|
||||
unified_skins
|
|
@ -0,0 +1,73 @@
|
|||
local time = 0
|
||||
local update_time = tonumber(minetest.setting_get("wieldview_update_time"))
|
||||
if not update_time then
|
||||
update_time = 2
|
||||
minetest.setting_set("wieldview_update_time", tostring(update_time))
|
||||
end
|
||||
local node_tiles = minetest.setting_getbool("wieldview_node_tiles")
|
||||
if not node_tiles then
|
||||
node_tiles = false
|
||||
minetest.setting_set("wieldview_node_tiles", "false")
|
||||
end
|
||||
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua")
|
||||
|
||||
wieldview = {
|
||||
wielded_item = {},
|
||||
}
|
||||
|
||||
wieldview.get_item_texture = function(self, item)
|
||||
local texture = uniskins.default_texture
|
||||
if item ~= "" then
|
||||
if minetest.registered_items[item] then
|
||||
if minetest.registered_items[item].inventory_image ~= "" then
|
||||
texture = minetest.registered_items[item].inventory_image
|
||||
elseif node_tiles == true and minetest.registered_items[item].tiles then
|
||||
texture = minetest.registered_items[item].tiles[1]
|
||||
end
|
||||
end
|
||||
if wieldview_transform[item] then
|
||||
texture = texture.."^[transform"..wieldview_transform[item]
|
||||
end
|
||||
end
|
||||
return texture
|
||||
end
|
||||
|
||||
wieldview.update_wielded_item = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local stack = player:get_wielded_item()
|
||||
local item = stack:get_name()
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
if self.wielded_item[name] then
|
||||
if self.wielded_item[name] == item then
|
||||
return
|
||||
end
|
||||
uniskins.wielditem[name] = self:get_item_texture(item)
|
||||
uniskins:update_player_visuals(player)
|
||||
end
|
||||
self.wielded_item[name] = item
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
wieldview.wielded_item[name] = ""
|
||||
minetest.after(0, function(player)
|
||||
wieldview:update_wielded_item(player)
|
||||
end, player)
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
if time > update_time then
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
wieldview:update_wielded_item(player)
|
||||
end
|
||||
time = 0
|
||||
end
|
||||
end)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
-- Wielded Item Transformations - http://dev.minetest.net/texture
|
||||
|
||||
wieldview_transform = {
|
||||
["default:torch"]="R270",
|
||||
["default:sapling"]="R270",
|
||||
["flowers:dandelion_white"]="R270",
|
||||
["flowers:dandelion_yellow"]="R270",
|
||||
["flowers:geranium"]="R270",
|
||||
["flowers:rose"]="R270",
|
||||
["flowers:tulip"]="R270",
|
||||
["flowers:viola"]="R270",
|
||||
["bucket:bucket_empty"]="R270",
|
||||
["bucket:bucket_water"]="R270",
|
||||
["bucket:bucket_lava"]="R270",
|
||||
["screwdriver:screwdriver"]="R270",
|
||||
["screwdriver:screwdriver1"]="R270",
|
||||
["screwdriver:screwdriver2"]="R270",
|
||||
["screwdriver:screwdriver3"]="R270",
|
||||
["screwdriver:screwdriver4"]="R270",
|
||||
["vessels:glass_bottle"]="R270",
|
||||
["vessels:drinking_glass"]="R270",
|
||||
["vessels:steel_bottle"]="R270",
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
*~
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,99 @@
|
|||
Areas mod for Minetest 0.4.8+
|
||||
=============================
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
If you wish to specify configuration options, such as whether players are
|
||||
allowed to protect their own areas with /protect (Disabled by default), you
|
||||
should check config.lua and set the apropriate settings in your minetest.conf.
|
||||
|
||||
|
||||
Tutorial
|
||||
--------
|
||||
To protect an area you must first set the corner positions of the area.
|
||||
In order to set the corner positions you run:
|
||||
1. "/area\_pos set" punch the two border nodes.
|
||||
2. "/area\_pos set1/2" punch only the first or second border node.
|
||||
3. "/area\_pos1/2" set position one or two to your current position.
|
||||
4. "/area\_pos1/2 X Y Z" set position one or two to the specified coordinates.
|
||||
|
||||
Once you have set the border positions you can protect the area by running:
|
||||
1. "/set\_owner <OwnerName> <AreaName>"
|
||||
-- If you are a administrator or moderator with the "areas" privilege.
|
||||
2. "/protect <AreaName>"
|
||||
-- If the server administraor has enabled area self-protection.
|
||||
|
||||
The area name is used so that you can easily find the area that you want when
|
||||
using a command like /list\_areas. It is not used for any other purpose.
|
||||
For example: /set\_owner SomePlayer Diamond city
|
||||
|
||||
Now that you own a area you may want to add sub-owners to it. You can do this
|
||||
with the /add\_owner command. Anyone with a area can use the add\_owner
|
||||
command on their areas. Before using the add\_owner command you have to select
|
||||
the corners of the sub-area as you did for set\_owner. If your markers are
|
||||
still around your origional area and you want to grant access to your entire
|
||||
area you will not have to re-set them. You can also use select\_area to place
|
||||
the markers at the corners of an existing area.
|
||||
The add\_owner command expects three arguments:
|
||||
1. The id of the parent area. (The area that you want it to be a sub-area of)
|
||||
2. The name of the player that will own the sub-area.
|
||||
3. The name of the sub-area.
|
||||
|
||||
For example: /add\_owner 123 BobTheBuilder Diamond lighthouse
|
||||
|
||||
Chat commands
|
||||
-------------
|
||||
* /protect <AreaName>
|
||||
Protects a area for yourself. (If self-protection is enabled)
|
||||
|
||||
* /set\_owner <OwnerName> <AreaName>
|
||||
Protects a area. (Requires the "areas" privilege)
|
||||
|
||||
* /add\_owner <ParentID> <OwnerName> <ChildName>
|
||||
Grants annother player control over part(or all) of a area.
|
||||
|
||||
* /rename\_area <ID> <NewName>
|
||||
Renames a existing area, usefull after converting from node_ownership
|
||||
when all areas are unnamed.
|
||||
|
||||
* /list\_areas
|
||||
Lists all of the areas that you own.
|
||||
(Or all of them if you have the "areas" privilege)
|
||||
|
||||
* /find\_areas <Regex>
|
||||
Finds areas using a Lua regular expresion.
|
||||
For example:
|
||||
/find_areas [Cc]astle To find castles.
|
||||
|
||||
* /remove\_area <ID>
|
||||
Removes a area that you own. Any sub-areas of that area are made sub-areas
|
||||
of the removed area's parent, if it exists. Otherwise they will have no
|
||||
parent.
|
||||
|
||||
* /recursive\_remove\_areas <ID>
|
||||
Removes a area and all sub-areas of it.
|
||||
|
||||
* /change\_owner <ID> <NewOwner>
|
||||
Change the owner of a area.
|
||||
|
||||
* /select\_area <ID>
|
||||
Sets the area positions to those of an existing area.
|
||||
|
||||
* /area\_pos {set,set1,set2,get}
|
||||
Sets the area positions by punching nodes or shows the current area positions.
|
||||
|
||||
* /area\_pos1 \[X,Y,Z|X Y Z\]
|
||||
Sets area position one to your position or the one supplied.
|
||||
|
||||
* /area\_pos2 \[X,Y,Z|X Y Z\]
|
||||
Sets area position two to your position or the one supplied.
|
||||
|
||||
License
|
||||
-------
|
||||
Copyright (C) 2013 ShadowNinja
|
||||
|
||||
Licensed under the GNU LGPL version 2.1 or higher.
|
||||
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
-- Returns a list of areas that include the provided position
|
||||
function areas:getAreasAtPos(pos)
|
||||
local a = {}
|
||||
local px, py, pz = pos.x, pos.y, pos.z
|
||||
for id, area in pairs(self.areas) do
|
||||
local ap1, ap2 = area.pos1, area.pos2
|
||||
if px >= ap1.x and px <= ap2.x and
|
||||
py >= ap1.y and py <= ap2.y and
|
||||
pz >= ap1.z and pz <= ap2.z then
|
||||
a[id] = area
|
||||
end
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
-- Checks if the area is unprotected or owned by you
|
||||
function areas:canInteract(pos, name)
|
||||
if minetest.check_player_privs(name, {areas=true}) then
|
||||
return true
|
||||
end
|
||||
local owned = false
|
||||
for _, area in pairs(self:getAreasAtPos(pos)) do
|
||||
if area.owner == name then
|
||||
return true
|
||||
else
|
||||
owned = true
|
||||
end
|
||||
end
|
||||
return not owned
|
||||
end
|
||||
|
||||
-- Returns a table (list) of all players that own an area
|
||||
function areas:getNodeOwners(pos)
|
||||
local owners = {}
|
||||
for _, area in pairs(self:getAreasAtPos(pos)) do
|
||||
table.insert(owners, area.owner)
|
||||
end
|
||||
return owners
|
||||
end
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
|
||||
minetest.register_chatcommand("protect", {
|
||||
params = "<AreaName>",
|
||||
description = "Protect your own area",
|
||||
privs = {[areas.self_protection_privilege]=true},
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name, 'Invalid usage, see /help protect')
|
||||
return
|
||||
end
|
||||
local pos1, pos2 = areas:getPos1(name), areas:getPos2(name)
|
||||
if pos1 and pos2 then
|
||||
pos1, pos2 = areas:sortPos(pos1, pos2)
|
||||
else
|
||||
minetest.chat_send_player(name, 'You need to select an area first')
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", "/protect invoked, owner="..name..
|
||||
" areaname="..param..
|
||||
" startpos="..minetest.pos_to_string(pos1)..
|
||||
" endpos=" ..minetest.pos_to_string(pos2))
|
||||
|
||||
local canAdd, errMsg = areas:canPlayerAddArea(pos1, pos2, name)
|
||||
if not canAdd then
|
||||
minetest.chat_send_player(name,
|
||||
"You can't protect that area: "
|
||||
..errMsg)
|
||||
return
|
||||
end
|
||||
|
||||
local id = areas:add(name, param, pos1, pos2, nil)
|
||||
areas:save()
|
||||
|
||||
minetest.chat_send_player(name, "Area protected. ID: "..id)
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("set_owner", {
|
||||
params = "<PlayerName> <AreaName>",
|
||||
description = "Protect an area beetween two positions and give"
|
||||
.." a player access to it without setting the parent of the"
|
||||
.." area to any existing area",
|
||||
privs = {areas=true},
|
||||
func = function(name, param)
|
||||
local found, _, ownername, areaname = param:find('^([^ ]+) (.+)$')
|
||||
|
||||
if not found then
|
||||
minetest.chat_send_player(name, "Incorrect usage, see /help set_owner")
|
||||
return
|
||||
end
|
||||
|
||||
local pos1, pos2 = areas:getPos1(name), areas:getPos2(name)
|
||||
if pos1 and pos2 then
|
||||
pos1, pos2 = areas:sortPos(pos1, pos2)
|
||||
else
|
||||
minetest.chat_send_player(name, "You need to select an area first")
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:player_exists(ownername) then
|
||||
minetest.chat_send_player(name, "The player \""
|
||||
..ownername.."\" does not exist")
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", name.." runs /set_owner. Owner = "..ownername..
|
||||
" AreaName = "..areaname..
|
||||
" StartPos = "..minetest.pos_to_string(pos1)..
|
||||
" EndPos = " ..minetest.pos_to_string(pos2))
|
||||
|
||||
local id = areas:add(ownername, areaname, pos1, pos2, nil)
|
||||
areas:save()
|
||||
|
||||
minetest.chat_send_player(ownername,
|
||||
"You have been granted control over area #"..
|
||||
id..". Type /list_areas to show your areas.")
|
||||
minetest.chat_send_player(name, "Area protected. ID: "..id)
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("add_owner", {
|
||||
params = "<ParentID> <Player> <AreaName>",
|
||||
description = "Give a player access to a sub-area beetween two"
|
||||
.." positions that have already been protected,"
|
||||
.." Use set_owner if you don't want the parent to be set.",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local found, _, pid, ownername, areaname
|
||||
= param:find('^(%d+) ([^ ]+) (.+)$')
|
||||
|
||||
if not found then
|
||||
minetest.chat_send_player(name, "Incorrect usage, see /help add_owner")
|
||||
return
|
||||
end
|
||||
|
||||
local pos1, pos2 = areas:getPos1(name), areas:getPos2(name)
|
||||
if pos1 and pos2 then
|
||||
pos1, pos2 = areas:sortPos(pos1, pos2)
|
||||
else
|
||||
minetest.chat_send_player(name, 'You need to select an area first')
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:player_exists(ownername) then
|
||||
minetest.chat_send_player(name, 'The player "'
|
||||
..ownername..'" does not exist')
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", name.." runs /add_owner. Owner = "..ownername..
|
||||
" AreaName = "..areaname.." ParentID = "..pid..
|
||||
" StartPos = "..pos1.x..","..pos1.y..","..pos1.z..
|
||||
" EndPos = " ..pos2.x..","..pos2.y..","..pos2.z)
|
||||
|
||||
-- Check if this new area is inside an area owned by the player
|
||||
pid = tonumber(pid)
|
||||
if (not areas:isAreaOwner(pid, name)) or
|
||||
(not areas:isSubarea(pos1, pos2, pid)) then
|
||||
minetest.chat_send_player(name,
|
||||
"You can't protect that area")
|
||||
return
|
||||
end
|
||||
|
||||
local id = areas:add(ownername, areaname, pos1, pos2, pid)
|
||||
areas:save()
|
||||
|
||||
minetest.chat_send_player(ownername,
|
||||
"You have been granted control over area #"..
|
||||
id..". Type /list_areas to show your areas.")
|
||||
minetest.chat_send_player(name, "Area protected. ID: "..id)
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("rename_area", {
|
||||
params = "<ID> <newName>",
|
||||
description = "Rename a area that you own",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local found, _, id, newName = param:find("^(%d+) (.+)$")
|
||||
if not found then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see /help rename_area")
|
||||
return
|
||||
end
|
||||
|
||||
id = tonumber(id)
|
||||
if not id then
|
||||
minetest.chat_send_player(name, "That area doesn't exist.")
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:isAreaOwner(id, name) then
|
||||
minetest.chat_send_player(name, "You don't own that area.")
|
||||
return
|
||||
end
|
||||
|
||||
areas.areas[id].name = newName
|
||||
areas:save()
|
||||
minetest.chat_send_player(name, "Area renamed.")
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("find_areas", {
|
||||
params = "<regexp>",
|
||||
description = "Find areas using a Lua regular expression",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name,
|
||||
"A regular expression is required.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Check expression for validity
|
||||
local function testRegExp()
|
||||
("Test [1]: Player (0,0,0) (0,0,0)"):find(param)
|
||||
end
|
||||
if not pcall(testRegExp) then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid regular expression.")
|
||||
return
|
||||
end
|
||||
|
||||
local found = false
|
||||
for id, area in pairs(areas.areas) do
|
||||
if areas:isAreaOwner(id, name) and
|
||||
areas:toString(id):find(param) then
|
||||
minetest.chat_send_player(name, areas:toString(id))
|
||||
found = true
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
minetest.chat_send_player(name, "No matches found")
|
||||
end
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("list_areas", {
|
||||
params = "",
|
||||
description = "List your areas, or all areas if you are an admin.",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local admin = minetest.check_player_privs(name, {areas=true})
|
||||
if admin then
|
||||
minetest.chat_send_player(name,
|
||||
"Showing all areas.")
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Showing your areas.")
|
||||
end
|
||||
for id, area in pairs(areas.areas) do
|
||||
if admin or areas:isAreaOwner(id, name) then
|
||||
minetest.chat_send_player(name,
|
||||
areas:toString(id))
|
||||
end
|
||||
end
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("recursive_remove_areas", {
|
||||
params = "<id>",
|
||||
description = "Recursively remove areas using an id",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local id = tonumber(param)
|
||||
if not id then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see"
|
||||
.." /help recursive_remove_areas")
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:isAreaOwner(id, name) then
|
||||
minetest.chat_send_player(name, "Area "..id
|
||||
.." does not exist or is"
|
||||
.." not owned by you.")
|
||||
return
|
||||
end
|
||||
|
||||
areas:remove(id, true)
|
||||
areas:save()
|
||||
minetest.chat_send_player(name, "Removed area "..id
|
||||
.." and it's sub areas.")
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("remove_area", {
|
||||
params = "<id>",
|
||||
description = "Remove an area using an id",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local id = tonumber(param)
|
||||
if not id then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see /help remove_area")
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:isAreaOwner(id, name) then
|
||||
minetest.chat_send_player(name, "Area "..id
|
||||
.." does not exist or"
|
||||
.." is not owned by you")
|
||||
return
|
||||
end
|
||||
|
||||
areas:remove(id)
|
||||
areas:save()
|
||||
minetest.chat_send_player(name, 'Removed area '..id)
|
||||
end})
|
||||
|
||||
|
||||
minetest.register_chatcommand("change_owner", {
|
||||
params = "<id> <NewOwner>",
|
||||
description = "Change the owner of an area using its id",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local found, _, id, new_owner =
|
||||
param:find('^(%d+) ([^ ]+)$')
|
||||
|
||||
if not found then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage,"
|
||||
.." see /help change_area_owner")
|
||||
return
|
||||
end
|
||||
|
||||
if not areas:player_exists(new_owner) then
|
||||
minetest.chat_send_player(name, 'The player "'
|
||||
..new_owner..'" does not exist')
|
||||
return
|
||||
end
|
||||
|
||||
id = tonumber(id)
|
||||
if not areas:isAreaOwner(id, name) then
|
||||
minetest.chat_send_player(name,
|
||||
"Area "..id.." does not exist"
|
||||
.." or is not owned by you.")
|
||||
return
|
||||
end
|
||||
areas.areas[id].owner = new_owner
|
||||
areas:save()
|
||||
minetest.chat_send_player(name, 'Owner changed.')
|
||||
minetest.chat_send_player(new_owner,
|
||||
name..'" has given you control over an area.')
|
||||
end})
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
-- This is inspired by the landrush mod by Bremaweb
|
||||
|
||||
areas.hud = {}
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
local pos = vector.round(player:getpos())
|
||||
local a = areas:getAreasAtPos(pos)
|
||||
local areaString = ""
|
||||
local first = true
|
||||
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||
if not first then
|
||||
areaString = areaString..", "
|
||||
else
|
||||
first = false
|
||||
end
|
||||
areaString = areaString..id.." ("..area.owner..")"
|
||||
end
|
||||
if not areas.hud[name] then
|
||||
areas.hud[name] = {}
|
||||
areas.hud[name].areasId = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
name = "Areas",
|
||||
number = 0xFFFFFF,
|
||||
position = {x=0, y=1},
|
||||
offset = {x=5, y=-60},
|
||||
direction = 0,
|
||||
text = "Areas: "..areaString,
|
||||
scale = {x=200, y=60},
|
||||
alignment = {x=1, y=1},
|
||||
})
|
||||
areas.hud[name].oldAreas = areaString
|
||||
return
|
||||
elseif areas.hud[name].oldAreas ~= areaString then
|
||||
player:hud_change(areas.hud[name].areasId, "text",
|
||||
"Areas: "..areaString)
|
||||
areas.hud[name].oldAreas = areaString
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
areas.hud[player:get_player_name()] = nil
|
||||
end)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
-- Areas mod by ShadowNinja
|
||||
-- Based on node_ownership
|
||||
-- License: LGPLv2+
|
||||
|
||||
areas = {}
|
||||
|
||||
areas.startTime = os.clock()
|
||||
|
||||
areas.modpath = minetest.get_modpath("areas")
|
||||
dofile(areas.modpath.."/settings.lua")
|
||||
dofile(areas.modpath.."/api.lua")
|
||||
dofile(areas.modpath.."/internal.lua")
|
||||
dofile(areas.modpath.."/chatcommands.lua")
|
||||
dofile(areas.modpath.."/pos.lua")
|
||||
dofile(areas.modpath.."/interact.lua")
|
||||
dofile(areas.modpath.."/legacy.lua")
|
||||
dofile(areas.modpath.."/hud.lua")
|
||||
|
||||
areas:load()
|
||||
|
||||
minetest.register_privilege("areas", {description = "Can administer areas"})
|
||||
|
||||
if not minetest.registered_privileges[areas.self_protection_privilege] then
|
||||
minetest.register_privilege(areas.self_protection_privilege, {
|
||||
description = "Can protect areas",
|
||||
})
|
||||
end
|
||||
|
||||
if minetest.setting_getbool("log_mod") then
|
||||
local diffTime = os.clock() - areas.startTime
|
||||
minetest.log("action", "areas loaded in "..diffTime.."s.")
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
local old_is_protected = minetest.is_protected
|
||||
function minetest.is_protected(pos, name)
|
||||
if not areas:canInteract(pos, name) then
|
||||
return true
|
||||
end
|
||||
return old_is_protected(pos, name)
|
||||
end
|
||||
|
||||
minetest.register_on_protection_violation(function(pos, name)
|
||||
if not areas:canInteract(pos, name) then
|
||||
local owners = areas:getNodeOwners(pos)
|
||||
minetest.chat_send_player(name,
|
||||
("%s is protected by %s."):format(
|
||||
minetest.pos_to_string(pos),
|
||||
table.concat(owners, ", ")))
|
||||
end
|
||||
end)
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
|
||||
function areas:player_exists(name)
|
||||
return minetest.auth_table[name] ~= nil
|
||||
end
|
||||
|
||||
-- Save the areas table to a file
|
||||
function areas:save()
|
||||
local file, err = io.open(self.filename, "w")
|
||||
if err then
|
||||
return err
|
||||
end
|
||||
file:write(minetest.serialize(self.areas))
|
||||
file:close()
|
||||
end
|
||||
|
||||
-- Load the areas table from the save file
|
||||
function areas:load()
|
||||
local file, err = io.open(self.filename, "r")
|
||||
if err then
|
||||
self.areas = self.areas or {}
|
||||
return err
|
||||
end
|
||||
self.areas = minetest.deserialize(file:read("*a"))
|
||||
if type(self.areas) ~= "table" then
|
||||
self.areas = {}
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
|
||||
-- Finds the first usable index in a table
|
||||
-- Eg: {[1]=false,[4]=true} -> 2
|
||||
local function findFirstUnusedIndex(t)
|
||||
local i = 0
|
||||
repeat i = i + 1
|
||||
until t[i] == nil
|
||||
return i
|
||||
end
|
||||
|
||||
-- Add a area, returning the new area's id.
|
||||
function areas:add(owner, name, pos1, pos2, parent)
|
||||
local id = findFirstUnusedIndex(self.areas)
|
||||
self.areas[id] = {name=name, pos1=pos1, pos2=pos2, owner=owner,
|
||||
parent=parent}
|
||||
return id
|
||||
end
|
||||
|
||||
-- Remove a area, and optionally it's children recursively.
|
||||
-- If a area is deleted non-recursively the children will
|
||||
-- have the removed area's parent as their new parent.
|
||||
function areas:remove(id, recurse, secondrun)
|
||||
if recurse then
|
||||
-- Recursively find child entries and remove them
|
||||
local cids = self:getChildren(id)
|
||||
for _, cid in pairs(cids) do
|
||||
self:remove(cid, true, true)
|
||||
end
|
||||
else
|
||||
-- Update parents
|
||||
local parent = self.areas[id].parent
|
||||
local children = self:getChildren(id)
|
||||
for _, cid in pairs(children) do
|
||||
-- The subarea parent will be niled out if the
|
||||
-- removed area does not have a parent
|
||||
self.areas[cid].parent = parent
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove main entry
|
||||
self.areas[id] = nil
|
||||
end
|
||||
|
||||
-- Checks if a area between two points is entirely contained by another area
|
||||
function areas:isSubarea(pos1, pos2, id)
|
||||
local area = self.areas[id]
|
||||
if not area then
|
||||
return false
|
||||
end
|
||||
p1, p2 = area.pos1, area.pos2
|
||||
if (pos1.x >= p1.x and pos1.x <= p2.x) and
|
||||
(pos2.x >= p1.x and pos2.x <= p2.x) and
|
||||
(pos1.y >= p1.y and pos1.y <= p2.y) and
|
||||
(pos2.y >= p1.y and pos2.y <= p2.y) and
|
||||
(pos1.z >= p1.z and pos1.z <= p2.z) and
|
||||
(pos2.z >= p1.z and pos2.z <= p2.z) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns a table (list) of children of an area given it's identifier
|
||||
function areas:getChildren(id)
|
||||
local children = {}
|
||||
for cid, area in pairs(self.areas) do
|
||||
if area.parent and area.parent == id then
|
||||
table.insert(children, cid)
|
||||
end
|
||||
end
|
||||
return children
|
||||
end
|
||||
|
||||
-- Checks if the user has sufficient privileges.
|
||||
-- If the player is not a administrator it also checks
|
||||
-- if the area intersects other areas that they do not own.
|
||||
-- Also checks the size of the area and if the user already
|
||||
-- has more than max_areas.
|
||||
function areas:canPlayerAddArea(pos1, pos2, name)
|
||||
if minetest.check_player_privs(name, {areas=true}) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check self protection privilege, if it is enabled,
|
||||
-- and if the area is too big.
|
||||
if (not self.self_protection) or
|
||||
(not minetest.check_player_privs(name,
|
||||
{[areas.self_protection_privilege]=true})) then
|
||||
return false, "Self protection is disabled or you do not have"
|
||||
.." the necessary privilege."
|
||||
end
|
||||
|
||||
if (pos2.x - pos1.x) > self.self_protection_max_size.x or
|
||||
(pos2.y - pos1.y) > self.self_protection_max_size.y or
|
||||
(pos2.z - pos1.z) > self.self_protection_max_size.z then
|
||||
return false, "Area is too big."
|
||||
end
|
||||
|
||||
-- Check number of areas the user has and make sure it not above the max
|
||||
if self.self_protection then
|
||||
local count = 0
|
||||
for _, area in pairs(self.areas) do
|
||||
if area.owner == name then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > self.self_protection_max_areas then
|
||||
return false, "You have reached the maximum amount"
|
||||
.." of areas that you are allowed to"
|
||||
.." protect."
|
||||
end
|
||||
end
|
||||
|
||||
-- Check intersecting areas
|
||||
for _, area in pairs(self.areas) do
|
||||
if (area.pos1.x <= pos2.x and area.pos2.x >= pos1.x) and
|
||||
(area.pos1.y <= pos2.y and area.pos2.y >= pos1.y) and
|
||||
(area.pos1.z <= pos2.z and area.pos2.z >= pos1.z) then
|
||||
--Found an area intersecting with the suplied area
|
||||
if area.owner ~= name then
|
||||
return false, "The area intersects with an"
|
||||
.." area that you do not own."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true, ""
|
||||
end
|
||||
|
||||
-- Given a id returns a string in the format:
|
||||
-- "name [id]: owner (x1, y1, z1) (x2, y2, z2) -> children"
|
||||
function areas:toString(id)
|
||||
local area = self.areas[id]
|
||||
local message = ("%s [%d]: %s %s %s"):format(
|
||||
area.name, id, area.owner,
|
||||
minetest.pos_to_string(area.pos1),
|
||||
minetest.pos_to_string(area.pos2))
|
||||
|
||||
local children = areas:getChildren(id)
|
||||
if #children > 0 then
|
||||
message = message.." -> "..table.concat(children, ", ")
|
||||
end
|
||||
return message
|
||||
end
|
||||
|
||||
-- Re-order areas in table by their identifiers
|
||||
function areas:sort()
|
||||
local sa = {}
|
||||
for k, area in pairs(self.areas) do
|
||||
if not area.parent then
|
||||
table.insert(sa, area)
|
||||
local newid = #sa
|
||||
for _, subarea in pairs(self.areas) do
|
||||
if subarea.parent == k then
|
||||
subarea.parent = newid
|
||||
table.insert(sa, subarea)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.areas = sa
|
||||
end
|
||||
|
||||
-- Checks if a player owns an area or a parent of it
|
||||
function areas:isAreaOwner(id, name)
|
||||
local cur = self.areas[id]
|
||||
if cur and minetest.check_player_privs(name, {areas=true}) then
|
||||
return true
|
||||
end
|
||||
while cur do
|
||||
if cur.owner == name then
|
||||
return true
|
||||
elseif cur.parent then
|
||||
cur = self.areas[cur.parent]
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
-- This file contains functions to convert from
|
||||
-- the old areas format and other compatability code.
|
||||
|
||||
minetest.register_chatcommand("legacy_load_areas", {
|
||||
params = "<version>",
|
||||
description = "Loads, converts, and saves the areas from"
|
||||
.." a legacy save file.",
|
||||
privs = {areas=true, server=true, privs=true},
|
||||
func = function(name, param)
|
||||
minetest.chat_send_player(name, "Converting areas...")
|
||||
local version = tonumber(param)
|
||||
if version == 0 then
|
||||
err = areas:node_ownership_load()
|
||||
if err then
|
||||
minetest.chat_send_player(name, "Error loading legacy file: "..err)
|
||||
return
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name, "Invalid version number. (0 allowed)")
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(name, "Legacy file loaded.")
|
||||
|
||||
for k, area in pairs(areas.areas) do
|
||||
-- New position format
|
||||
area.pos1 = {x=area.x1, y=area.y1, z=area.z1}
|
||||
area.pos2 = {x=area.x2, y=area.y2, z=area.z2}
|
||||
|
||||
area.x1, area.y1, area.z1,
|
||||
area.x2, area.y2, area.z2 =
|
||||
nil, nil, nil, nil, nil, nil
|
||||
|
||||
-- Area positions sorting
|
||||
area.pos1, area.pos2 = areas:sortPos(area.pos1, area.pos2)
|
||||
|
||||
-- Add name
|
||||
area.name = "unnamed"
|
||||
|
||||
-- Remove ID
|
||||
area.id = nil
|
||||
end
|
||||
minetest.chat_send_player(name, "Table format updated.")
|
||||
|
||||
areas:save()
|
||||
minetest.chat_send_player(name, "Converted areas saved. Done.")
|
||||
end})
|
||||
|
||||
function areas:node_ownership_load()
|
||||
local filename = minetest.get_worldpath().."/owners.tbl"
|
||||
tables, err = loadfile(filename)
|
||||
if err then
|
||||
return err
|
||||
end
|
||||
|
||||
tables = tables()
|
||||
for idx = 1, #tables do
|
||||
local tolinkv, tolinki = {}, {}
|
||||
for i, v in pairs(tables[idx]) do
|
||||
if type(v) == "table" and tables[v[1]] then
|
||||
table.insert(tolinkv, {i, tables[v[1]]})
|
||||
end
|
||||
if type(i) == "table" and tables[i[1]] then
|
||||
table.insert(tolinki, {i, tables[i[1]]})
|
||||
end
|
||||
end
|
||||
-- link values, first due to possible changes of indices
|
||||
for _, v in ipairs(tolinkv) do
|
||||
tables[idx][v[1]] = v[2]
|
||||
end
|
||||
-- link indices
|
||||
for _, v in ipairs(tolinki) do
|
||||
tables[idx][v[2]], tables[idx][v[1]] = tables[idx][v[1]], nil
|
||||
end
|
||||
end
|
||||
self.areas = tables[1]
|
||||
end
|
||||
|
||||
-- Returns the name of the first player that owns an area
|
||||
function areas.getNodeOwnerName(pos)
|
||||
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||
return area.owner
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Checks if a node is owned by you
|
||||
function areas.isNodeOwner(pos, name)
|
||||
if minetest.check_player_privs(name, {areas=true}) then
|
||||
return true
|
||||
end
|
||||
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||
if name == area.owner then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Checks if an area has an owner
|
||||
function areas.hasOwner(pos)
|
||||
for id, area in pairs(areas:getAreasAtPos(pos)) do
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
IsPlayerNodeOwner = areas.isNodeOwner
|
||||
GetNodeOwnerName = areas.getNodeOwnerName
|
||||
HasOwner = areas.hasOwner
|
||||
|
||||
-- This is entirely untested and may break in strange and new ways.
|
||||
if areas.legacy_table then
|
||||
owner_defs = {}
|
||||
setmetatable(owner_defs, {
|
||||
__index = function(table, key)
|
||||
local a = rawget(areas.areas, key)
|
||||
if a then
|
||||
a.x1 = a.pos1.x
|
||||
a.y1 = a.pos1.y
|
||||
a.z1 = a.pos1.z
|
||||
a.x2 = a.pos2.x
|
||||
a.y2 = a.pos2.y
|
||||
a.z2 = a.pos2.z
|
||||
a.pos1, a.pos2 = nil, nil
|
||||
a.id = key
|
||||
end
|
||||
return a
|
||||
end,
|
||||
__newindex = function(table, key, value)
|
||||
local a = value
|
||||
a.pos1, a.pos2 = {}, {}
|
||||
a.pos1.x = a.x1
|
||||
a.pos1.y = a.y1
|
||||
a.pos1.z = a.z1
|
||||
a.pos2.x = a.x2
|
||||
a.pos2.y = a.y2
|
||||
a.pos2.z = a.z2
|
||||
a.x1, a.y1, a.z1, a.x2, a.y2, a.z2 =
|
||||
nil, nil, nil, nil, nil, nil
|
||||
a.name = a.name or "unnamed"
|
||||
a.id = nil
|
||||
return rawset(areas.areas, key, a)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
|
||||
-- I could depend on WorldEdit for this, but you need to have the 'worldedit'
|
||||
-- permission to use those commands and you don't have
|
||||
-- /area_pos{1,2} [X Y Z|X,Y,Z].
|
||||
-- Since this is mostly copied from WorldEdit it is mostly
|
||||
-- licensed under the AGPL. (select_area is a exception)
|
||||
|
||||
areas.marker1 = {}
|
||||
areas.marker2 = {}
|
||||
areas.set_pos = {}
|
||||
areas.pos1 = {}
|
||||
areas.pos2 = {}
|
||||
|
||||
minetest.register_chatcommand("select_area", {
|
||||
params = "<id>",
|
||||
description = "Select a area by id.",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local id = tonumber(param)
|
||||
if not id then
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see /help select_area.")
|
||||
return
|
||||
end
|
||||
if not areas.areas[id] then
|
||||
minetest.chat_send_player(name,
|
||||
"The area "..id.." does not exist.")
|
||||
return
|
||||
end
|
||||
|
||||
areas:setPos1(name, areas.areas[id].pos1)
|
||||
areas:setPos2(name, areas.areas[id].pos2)
|
||||
minetest.chat_send_player(name,
|
||||
"Area "..id.." selected.")
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("area_pos1", {
|
||||
params = "[X Y Z|X,Y,Z]",
|
||||
description = "Set area protection region position 1 to your"
|
||||
.." location or the one specified",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local pos = nil
|
||||
local found, _, x, y, z = param:find(
|
||||
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
|
||||
if found then
|
||||
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||||
elseif param == "" then
|
||||
player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
pos = player:getpos()
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Unable to get position")
|
||||
return
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see /help area_pos1")
|
||||
return
|
||||
end
|
||||
pos = vector.round(pos)
|
||||
areas:setPos1(name, pos)
|
||||
minetest.chat_send_player(name,
|
||||
"Area position 1 set to "
|
||||
..minetest.pos_to_string(pos))
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("area_pos2", {
|
||||
params = "[X Y Z|X,Y,Z]",
|
||||
description = "Set area protection region position 2 to your"
|
||||
.." location or the one specified",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local pos = nil
|
||||
local found, _, x, y, z = param:find(
|
||||
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
|
||||
if found then
|
||||
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||||
elseif param == "" then
|
||||
player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
pos = player:getpos()
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Unable to get position")
|
||||
return
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Invalid usage, see /help area_pos2")
|
||||
return
|
||||
end
|
||||
pos = vector.round(pos)
|
||||
areas:setPos2(name, pos)
|
||||
minetest.chat_send_player(name,
|
||||
"Area position 2 set to "
|
||||
..minetest.pos_to_string(pos))
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("area_pos", {
|
||||
params = "set/set1/set2/get",
|
||||
description = "Set area protection region, position 1, or position 2"
|
||||
.." by punching nodes, or display the region",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
if param == "set" then -- Set both area positions
|
||||
areas.set_pos[name] = "pos1"
|
||||
minetest.chat_send_player(name,
|
||||
"Select positions by punching two nodes")
|
||||
elseif param == "set1" then -- Set area position 1
|
||||
areas.set_pos[name] = "pos1only"
|
||||
minetest.chat_send_player(name,
|
||||
"Select position 1 by punching a node")
|
||||
elseif param == "set2" then -- Set area position 2
|
||||
areas.set_pos[name] = "pos2"
|
||||
minetest.chat_send_player(name,
|
||||
"Select position 2 by punching a node")
|
||||
elseif param == "get" then -- Display current area positions
|
||||
if areas.pos1[name] ~= nil then
|
||||
minetest.chat_send_player(name, "Position 1: "
|
||||
..minetest.pos_to_string(areas.pos1[name]))
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Position 1 not set")
|
||||
end
|
||||
if areas.pos2[name] ~= nil then
|
||||
minetest.chat_send_player(name, "Position 2: "
|
||||
..minetest.pos_to_string(areas.pos2[name]))
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Position 2 not set")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name,
|
||||
"Unknown subcommand: "..param)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
function areas:getPos1(playerName)
|
||||
return areas.pos1[playerName]
|
||||
end
|
||||
|
||||
function areas:getPos2(playerName)
|
||||
return areas.pos2[playerName]
|
||||
end
|
||||
|
||||
function areas:setPos1(playerName, pos)
|
||||
areas.pos1[playerName] = pos
|
||||
areas.markPos1(playerName)
|
||||
end
|
||||
|
||||
function areas:setPos2(playerName, pos)
|
||||
areas.pos2[playerName] = pos
|
||||
areas.markPos2(playerName)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_punchnode(function(pos, node, puncher)
|
||||
local name = puncher:get_player_name()
|
||||
-- Currently setting position
|
||||
if name ~= "" and areas.set_pos[name] then
|
||||
if areas.set_pos[name] == "pos1" then
|
||||
areas.pos1[name] = pos
|
||||
areas.markPos1(name)
|
||||
areas.set_pos[name] = "pos2"
|
||||
minetest.chat_send_player(name,
|
||||
"Position 1 set to "
|
||||
..minetest.pos_to_string(pos))
|
||||
elseif areas.set_pos[name] == "pos1only" then
|
||||
areas.pos1[name] = pos
|
||||
areas.markPos1(name)
|
||||
areas.set_pos[name] = nil
|
||||
minetest.chat_send_player(name,
|
||||
"Position 1 set to "
|
||||
..minetest.pos_to_string(pos))
|
||||
elseif areas.set_pos[name] == "pos2" then
|
||||
areas.pos2[name] = pos
|
||||
areas.markPos2(name)
|
||||
areas.set_pos[name] = nil
|
||||
minetest.chat_send_player(name,
|
||||
"Position 2 set to "
|
||||
..minetest.pos_to_string(pos))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Modifies positions `pos1` and `pos2` so that each component of `pos1`
|
||||
-- is less than or equal to its corresponding component of `pos2`,
|
||||
-- returning two new positions
|
||||
function areas:sortPos(pos1, pos2)
|
||||
if pos1.x > pos2.x then
|
||||
pos2.x, pos1.x = pos1.x, pos2.x
|
||||
end
|
||||
if pos1.y > pos2.y then
|
||||
pos2.y, pos1.y = pos1.y, pos2.y
|
||||
end
|
||||
if pos1.z > pos2.z then
|
||||
pos2.z, pos1.z = pos1.z, pos2.z
|
||||
end
|
||||
return pos1, pos2
|
||||
end
|
||||
|
||||
-- Marks area position 1
|
||||
areas.markPos1 = function(name)
|
||||
local pos = areas.pos1[name]
|
||||
if areas.marker1[name] ~= nil then -- Marker already exists
|
||||
areas.marker1[name]:remove() -- Remove marker
|
||||
areas.marker1[name] = nil
|
||||
end
|
||||
if pos ~= nil then -- Add marker
|
||||
areas.marker1[name] = minetest.add_entity(pos, "areas:pos1")
|
||||
areas.marker1[name]:get_luaentity().active = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Marks area position 2
|
||||
areas.markPos2 = function(name)
|
||||
local pos = areas.pos2[name]
|
||||
if areas.marker2[name] ~= nil then -- Marker already exists
|
||||
areas.marker2[name]:remove() -- Remove marker
|
||||
areas.marker2[name] = nil
|
||||
end
|
||||
if pos ~= nil then -- Add marker
|
||||
areas.marker2[name] = minetest.add_entity(pos, "areas:pos2")
|
||||
areas.marker2[name]:get_luaentity().active = true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_entity("areas:pos1", {
|
||||
initial_properties = {
|
||||
visual = "cube",
|
||||
visual_size = {x=1.1, y=1.1},
|
||||
textures = {"areas_pos1.png", "areas_pos1.png",
|
||||
"areas_pos1.png", "areas_pos1.png",
|
||||
"areas_pos1.png", "areas_pos1.png"},
|
||||
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||
},
|
||||
on_step = function(self, dtime)
|
||||
if self.active == nil then
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
on_punch = function(self, hitter)
|
||||
self.object:remove()
|
||||
local name = hitter:get_player_name()
|
||||
areas.marker1[name] = nil
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_entity("areas:pos2", {
|
||||
initial_properties = {
|
||||
visual = "cube",
|
||||
visual_size = {x=1.1, y=1.1},
|
||||
textures = {"areas_pos2.png", "areas_pos2.png",
|
||||
"areas_pos2.png", "areas_pos2.png",
|
||||
"areas_pos2.png", "areas_pos2.png"},
|
||||
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||
},
|
||||
on_step = function(self, dtime)
|
||||
if self.active == nil then
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
on_punch = function(self, hitter)
|
||||
self.object:remove()
|
||||
local name = hitter:get_player_name()
|
||||
areas.marker2[name] = nil
|
||||
end,
|
||||
})
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
local worldpath = minetest.get_worldpath()
|
||||
|
||||
local function setting_getbool_default(setting, default)
|
||||
local value = minetest.setting_getbool(setting)
|
||||
if value == nil then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
areas.filename =
|
||||
minetest.setting_get("areas.filename") or worldpath.."/areas.dat"
|
||||
|
||||
-- Allow players with a privilege create their own areas
|
||||
-- within the max_size and number
|
||||
areas.self_protection =
|
||||
setting_getbool_default("areas.self_protection", true)
|
||||
areas.self_protection_privilege =
|
||||
minetest.setting_get("areas.self_protection_privilege") or "interact"
|
||||
areas.self_protection_max_size =
|
||||
minetest.setting_get_pos("areas.self_protection_max_size") or
|
||||
{x=200, y=200, z=200}
|
||||
areas.self_protection_max_areas =
|
||||
tonumber(minetest.setting_get("areas.self_protection_max_areas")) or 50
|
||||
|
||||
-- Register compatability functions for node_ownership.
|
||||
-- legacy_table (owner_defs) compatibility is untested
|
||||
-- and can not be used if security_safe_mod_api is on.
|
||||
areas.legacy_table =
|
||||
setting_getbool_default("areas.legacy_table", false)
|
||||
|
||||
-- Prevent players from punching nodes in a protected area.
|
||||
-- Usefull for things like delayers, usualy annoying and
|
||||
-- prevents usage of things like buttons.
|
||||
areas.protect_punches =
|
||||
setting_getbool_default("areas.protect_punches", false)
|
||||
|
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 157 B |
|
@ -0,0 +1,2 @@
|
|||
default
|
||||
locks?
|
|
@ -0,0 +1,255 @@
|
|||
--more_signs by addi
|
||||
--Code and Textures are under the CC by-sa 3.0 licence
|
||||
--see: http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
|
||||
|
||||
arrow_signs={}
|
||||
|
||||
function arrow_signs:savetext(pos, formname, fields, sender)
|
||||
|
||||
if not minetest.get_player_privs(sender:get_player_name())["interact"] then
|
||||
minetest.chat_send_player(sender:get_player_name(), "error: you don't have permission to edit the sign. you need the interact priv")
|
||||
return
|
||||
end
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or ""
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos))
|
||||
meta:set_string("text", fields.text)
|
||||
text = arrow_signs:create_lines(fields.text)
|
||||
meta:set_string("infotext", '"'..text..'"')
|
||||
i=0
|
||||
for wort in text:gfind("\n") do
|
||||
i=i+1
|
||||
end
|
||||
if i > 4 then
|
||||
minetest.chat_send_player(sender:get_player_name(),"\tInformation: \nYou've written more than 5 lines. \n it may be that not all lines are displayed. \n Please remove the last entry")
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function arrow_signs:create_lines(text)
|
||||
text = text:gsub("/", "\"\n\"")
|
||||
text = text:gsub("|", "\"\n\"")
|
||||
return text
|
||||
end
|
||||
|
||||
|
||||
local clone_registered = function(case,name)
|
||||
local params = {}
|
||||
local list
|
||||
if case == "item" then list = minetest.registered_items end
|
||||
if case == "node" then list = minetest.registered_nodes end
|
||||
if case == "craftitem" then list = minetest.registered_craftitems end
|
||||
if case == "tool" then list = minetest.registered_tools end
|
||||
if case == "entity" then list = minetest.registered_entities end
|
||||
if list then
|
||||
for k,v in pairs(list[name]) do
|
||||
params[k] = v
|
||||
end
|
||||
end
|
||||
return params
|
||||
end
|
||||
|
||||
-- usage
|
||||
local node = clone_registered("node","default:sign_wall")
|
||||
node.groups = {choppy=2,dig_immediate=2,attached_node=1,sign=1}
|
||||
minetest.register_node(":default:sign_wall", node)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--Sign right
|
||||
minetest.register_node("arrow_signs:wall_right", {
|
||||
description = "Sign right",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_right.png"},
|
||||
inventory_image = "arrow_sign_right.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,attached_node=1,sign=1},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_defaults(),
|
||||
on_construct = function(pos)
|
||||
--local n = minetest.env:get_node(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", "hack:sign_text_input")
|
||||
meta:set_string("infotext", "\"\"")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
arrow_signs:savetext(pos, formname, fields, sender)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
|
||||
-- sign left
|
||||
minetest.register_node("arrow_signs:wall_left", {
|
||||
description = "Sign left",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_left.png"},
|
||||
inventory_image = "arrow_sign_left.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,attached_node=1,sign=1},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_defaults(),
|
||||
on_construct = function(pos)
|
||||
--local n = minetest.env:get_node(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", "hack:sign_text_input")
|
||||
meta:set_string("infotext", "\"\"")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
arrow_signs:savetext(pos, formname, fields, sender)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
--Sign up
|
||||
minetest.register_node("arrow_signs:wall_up", {
|
||||
description = "Sign up",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_up.png"},
|
||||
inventory_image = "arrow_sign_up.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,attached_node=1,sign=1},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_defaults(),
|
||||
on_construct = function(pos)
|
||||
--local n = minetest.env:get_node(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", "hack:sign_text_input")
|
||||
meta:set_string("infotext", "\"\"")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
arrow_signs:savetext(pos, formname, fields, sender)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
--Sign down
|
||||
minetest.register_node("arrow_signs:wall_down", {
|
||||
description = "Sign down",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_down.png"},
|
||||
inventory_image = "arrow_sign_down.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,attached_node=1,sign=1},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_defaults(),
|
||||
on_construct = function(pos)
|
||||
--local n = minetest.env:get_node(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", "hack:sign_text_input")
|
||||
meta:set_string("infotext", "\"\"")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
arrow_signs:savetext(pos, formname, fields, sender)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--recipes
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:wall_right 1',
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'', 'group:sign', 'default:stick'},
|
||||
{'', '', ''},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:wall_left 1',
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'default:stick', 'group:sign', ''},
|
||||
{'', '', ''},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:wall_up 1',
|
||||
recipe = {
|
||||
{'', 'default:stick', ''},
|
||||
{'', 'group:sign', ''},
|
||||
{'', '', ''},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:wall_down 1',
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'', 'group:sign', ''},
|
||||
{'', 'default:stick', ''},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'default:sign_wall',
|
||||
recipe = {
|
||||
|
||||
{'group:sign'},
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_alias("more_signs:wall_right", "arrow_signs:wall_right")
|
||||
minetest.register_alias("sign_right", "arrow_signs:wall_right")
|
||||
|
||||
minetest.register_alias("more_signs:wall_left", "arrow_signs:wall_left")
|
||||
minetest.register_alias("sign_left", "arrow_signs:wall_left")
|
||||
|
||||
minetest.register_alias("more_signs:wall_up", "arrow_signs:wall_up")
|
||||
minetest.register_alias("sign_up", "arrow_signs:wall_up")
|
||||
|
||||
minetest.register_alias("more_signs:wall_down", "arrow_signs:wall_dowm")
|
||||
minetest.register_alias("sign_down", "arrow_signs:wall_down")
|
||||
|
||||
|
||||
if locks then
|
||||
local MODPATH = minetest.get_modpath("arrow_signs");
|
||||
dofile(MODPATH.."/shared_locked.lua")
|
||||
end
|
|
@ -0,0 +1,112 @@
|
|||
author: addi
|
||||
|
||||
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
You are free:
|
||||
|
||||
to Share — to copy, distribute and transmit the work
|
||||
to Remix — to adapt the work
|
||||
|
||||
|
||||
Under the following conditions:
|
||||
|
||||
Attribution — You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
|
||||
|
||||
Share Alike — If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
|
||||
"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.
|
||||
"Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.
|
||||
"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
|
||||
"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.
|
||||
"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
|
||||
"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
|
||||
"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
|
||||
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
|
||||
"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
|
||||
"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
|
||||
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
|
||||
|
||||
to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
|
||||
to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
|
||||
to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
|
||||
to Distribute and Publicly Perform Adaptations.
|
||||
|
||||
For the avoidance of doubt:
|
||||
Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
|
||||
Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
|
||||
Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
|
||||
|
||||
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
|
||||
|
||||
You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.
|
||||
You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
|
||||
If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
|
||||
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
|
||||
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
|
||||
Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
|
||||
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
|
||||
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
|
||||
The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sign_wall',
|
||||
recipe = {
|
||||
|
||||
{'more_signs:wall_up'},
|
||||
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'default:sign_wall',
|
||||
recipe = {
|
||||
|
||||
{'more_signs:wall_left'},
|
||||
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'default:sign_wall',
|
||||
recipe = {
|
||||
|
||||
{'more_signs:wall_right'},
|
||||
|
||||
}
|
||||
})
|
|
@ -0,0 +1,284 @@
|
|||
-- a sign
|
||||
minetest.register_node("arrow_signs:shared_locked_right", {
|
||||
description = "Shared locked sign right",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_right.png"},
|
||||
inventory_image = "arrow_sign_right.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,sign_locked=1},
|
||||
legacy_wallmounted = true,
|
||||
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
-- prepare the lock of the sign
|
||||
locks:lock_init( pos,
|
||||
"size[8,4]"..
|
||||
"field[0.3,0.6;6,0.7;text;Text:;]"..
|
||||
"field[0.3,3.6;6,0.7;locks_sent_lock_command;Locked sign. Type /help for help:;]"..
|
||||
"button_exit[6.3,3.2;1.7,0.7;locks_sent_input;Proceed]" );
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
locks:lock_set_owner( pos, placer, "Shared locked sign" );
|
||||
end,
|
||||
|
||||
|
||||
can_dig = function(pos,player)
|
||||
return locks:lock_allow_dig( pos, player );
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
|
||||
-- if the user already has the right to use this and did input text
|
||||
if( fields.text
|
||||
and ( not(fields.locks_sent_lock_command)
|
||||
or fields.locks_sent_lock_command=="")
|
||||
and locks:lock_allow_use( pos, sender )) then
|
||||
|
||||
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or "";
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos));
|
||||
meta:set_string("text", fields.text.." ["..sender:get_player_name().."]");
|
||||
meta:set_string("infotext", '"'..fields.text..'"'.." ["..sender:get_player_name().."]");
|
||||
|
||||
-- a command for the lock?
|
||||
else
|
||||
arrow_signs:savetext( pos, formname, fields, sender );
|
||||
end
|
||||
|
||||
end,
|
||||
});
|
||||
--left
|
||||
minetest.register_node("arrow_signs:shared_locked_left", {
|
||||
description = "Shared locked sign left",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_left.png"},
|
||||
inventory_image = "arrow_sign_left.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,sign_locked=1},
|
||||
legacy_wallmounted = true,
|
||||
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
-- prepare the lock of the sign
|
||||
locks:lock_init( pos,
|
||||
"size[8,4]"..
|
||||
"field[0.3,0.6;6,0.7;text;Text:;]"..
|
||||
"field[0.3,3.6;6,0.7;locks_sent_lock_command;Locked sign. Type /help for help:;]"..
|
||||
"button_exit[6.3,3.2;1.7,0.7;locks_sent_input;Proceed]" );
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
locks:lock_set_owner( pos, placer, "Shared locked sign" );
|
||||
end,
|
||||
|
||||
|
||||
can_dig = function(pos,player)
|
||||
return locks:lock_allow_dig( pos, player );
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
|
||||
-- if the user already has the right to use this and did input text
|
||||
if( fields.text
|
||||
and ( not(fields.locks_sent_lock_command)
|
||||
or fields.locks_sent_lock_command=="")
|
||||
and locks:lock_allow_use( pos, sender )) then
|
||||
|
||||
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or "";
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos));
|
||||
meta:set_string("text", fields.text.." ["..sender:get_player_name().."]");
|
||||
meta:set_string("infotext", '"'..fields.text..'"'.." ["..sender:get_player_name().."]");
|
||||
|
||||
-- a command for the lock?
|
||||
else
|
||||
arrow_signs:savetext( pos, formname, fields, sender );
|
||||
end
|
||||
|
||||
end,
|
||||
});
|
||||
--up
|
||||
minetest.register_node("arrow_signs:shared_locked_up", {
|
||||
description = "Shared locked sign up",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_up.png"},
|
||||
inventory_image = "arrow_sign_up.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,sign_locked=1},
|
||||
legacy_wallmounted = true,
|
||||
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
-- prepare the lock of the sign
|
||||
locks:lock_init( pos,
|
||||
"size[8,4]"..
|
||||
"field[0.3,0.6;6,0.7;text;Text:;]"..
|
||||
"field[0.3,3.6;6,0.7;locks_sent_lock_command;Locked sign. Type /help for help:;]"..
|
||||
"button_exit[6.3,3.2;1.7,0.7;locks_sent_input;Proceed]" );
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
locks:lock_set_owner( pos, placer, "Shared locked sign" );
|
||||
end,
|
||||
|
||||
|
||||
can_dig = function(pos,player)
|
||||
return locks:lock_allow_dig( pos, player );
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
|
||||
-- if the user already has the right to use this and did input text
|
||||
if( fields.text
|
||||
and ( not(fields.locks_sent_lock_command)
|
||||
or fields.locks_sent_lock_command=="")
|
||||
and locks:lock_allow_use( pos, sender )) then
|
||||
|
||||
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or "";
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos));
|
||||
meta:set_string("text", fields.text.." ["..sender:get_player_name().."]");
|
||||
meta:set_string("infotext", '"'..fields.text..'"'.." ["..sender:get_player_name().."]");
|
||||
|
||||
-- a command for the lock?
|
||||
else
|
||||
arrow_signs:savetext( pos, formname, fields, sender );
|
||||
end
|
||||
|
||||
end,
|
||||
});
|
||||
--down
|
||||
minetest.register_node("arrow_signs:shared_locked_down", {
|
||||
description = "Shared locked sign down",
|
||||
drawtype = "signlike",
|
||||
tiles = {"arrow_sign_down.png"},
|
||||
inventory_image = "arrow_sign_down.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
--wall_top = <default>
|
||||
--wall_bottom = <default>
|
||||
--wall_side = <default>
|
||||
},
|
||||
groups = {choppy=2,dig_immediate=2,sign_locked=1},
|
||||
legacy_wallmounted = true,
|
||||
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
-- prepare the lock of the sign
|
||||
locks:lock_init( pos,
|
||||
"size[8,4]"..
|
||||
"field[0.3,0.6;6,0.7;text;Text:;]"..
|
||||
"field[0.3,3.6;6,0.7;locks_sent_lock_command;Locked sign. Type /help for help:;]"..
|
||||
"button_exit[6.3,3.2;1.7,0.7;locks_sent_input;Proceed]" );
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
locks:lock_set_owner( pos, placer, "Shared locked sign" );
|
||||
end,
|
||||
|
||||
|
||||
can_dig = function(pos,player)
|
||||
return locks:lock_allow_dig( pos, player );
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
|
||||
-- if the user already has the right to use this and did input text
|
||||
if( fields.text
|
||||
and ( not(fields.locks_sent_lock_command)
|
||||
or fields.locks_sent_lock_command=="")
|
||||
and locks:lock_allow_use( pos, sender )) then
|
||||
|
||||
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or "";
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos));
|
||||
meta:set_string("text", fields.text.." ["..sender:get_player_name().."]");
|
||||
meta:set_string("infotext", '"'..fields.text..'"'.." ["..sender:get_player_name().."]");
|
||||
|
||||
-- a command for the lock?
|
||||
else
|
||||
arrow_signs:savetext( pos, formname, fields, sender );
|
||||
end
|
||||
|
||||
end,
|
||||
});
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:shared_locked_right',
|
||||
recipe = {
|
||||
{ 'arrow_signs:wall_right', 'locks:lock', '' },
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:shared_locked_left',
|
||||
recipe = {
|
||||
{ 'arrow_signs:wall_left', 'locks:lock', '' },
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:shared_locked_up',
|
||||
recipe = {
|
||||
{ 'arrow_signs:wall_up', 'locks:lock', '' },
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:shared_locked_down',
|
||||
recipe = {
|
||||
{ 'arrow_signs:wall_down', 'locks:lock', '' },
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'arrow_signs:shared_locked_right',
|
||||
recipe = {
|
||||
{ 'group:', 'locks:lock', '' },
|
||||
},
|
||||
})
|
After Width: | Height: | Size: 676 B |
After Width: | Height: | Size: 658 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 691 B |
|
@ -0,0 +1,26 @@
|
|||
Minetest 0.4 mod: bucket
|
||||
=========================
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2011-2012 Kahrl <kahrl@gmx.net>
|
||||
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Authors of media files
|
||||
-----------------------
|
||||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
default
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
-- Minetest 0.4 mod: bucket
|
||||
-- See README.txt for licensing and other information.
|
||||
|
||||
local LIQUID_MAX = 8 --The number of water levels when liquid_finite is enabled
|
||||
|
||||
minetest.register_alias("bucket", "bucket:bucket_empty")
|
||||
minetest.register_alias("bucket_water", "bucket:bucket_water")
|
||||
minetest.register_alias("bucket_lava", "bucket:bucket_lava")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'bucket:bucket_empty 1',
|
||||
recipe = {
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
{'', 'default:steel_ingot', ''},
|
||||
}
|
||||
})
|
||||
|
||||
bucket = {}
|
||||
bucket.liquids = {}
|
||||
|
||||
local function check_protection(pos, name, text)
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.log("action", (name ~= "" and name or "A mod")
|
||||
.. " tried to " .. text
|
||||
.. " at protected position "
|
||||
.. minetest.pos_to_string(pos)
|
||||
.. " with a bucket")
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Register a new liquid
|
||||
-- source = name of the source node
|
||||
-- flowing = name of the flowing node
|
||||
-- itemname = name of the new bucket item (or nil if liquid is not takeable)
|
||||
-- inventory_image = texture of the new bucket item (ignored if itemname == nil)
|
||||
-- This function can be called from any mod (that depends on bucket).
|
||||
function bucket.register_liquid(source, flowing, itemname, inventory_image, name)
|
||||
bucket.liquids[source] = {
|
||||
source = source,
|
||||
flowing = flowing,
|
||||
itemname = itemname,
|
||||
}
|
||||
bucket.liquids[flowing] = bucket.liquids[source]
|
||||
|
||||
if itemname ~= nil then
|
||||
minetest.register_craftitem(itemname, {
|
||||
description = name,
|
||||
inventory_image = inventory_image,
|
||||
stack_max = 1,
|
||||
liquids_pointable = true,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
-- Must be pointing to node
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
if itemstack:get_name() == "bucket:bucket_lava" then
|
||||
return
|
||||
end
|
||||
|
||||
local node = minetest.get_node_or_nil(pointed_thing.under)
|
||||
local ndef
|
||||
if node then
|
||||
ndef = minetest.registered_nodes[node.name]
|
||||
end
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
if ndef and ndef.on_rightclick and
|
||||
user and not user:get_player_control().sneak then
|
||||
return ndef.on_rightclick(
|
||||
pointed_thing.under,
|
||||
node, user,
|
||||
itemstack) or itemstack
|
||||
end
|
||||
|
||||
local place_liquid = function(pos, node, source, flowing, fullness)
|
||||
if check_protection(pos,
|
||||
user and user:get_player_name() or "",
|
||||
"place "..source) then
|
||||
return
|
||||
end
|
||||
if math.floor(fullness/128) == 1 or
|
||||
not minetest.setting_getbool("liquid_finite") then
|
||||
minetest.add_node(pos, {name=source,
|
||||
param2=fullness})
|
||||
return
|
||||
elseif node.name == flowing then
|
||||
fullness = fullness + node.param2
|
||||
elseif node.name == source then
|
||||
fullness = LIQUID_MAX
|
||||
end
|
||||
|
||||
if fullness >= LIQUID_MAX then
|
||||
minetest.add_node(pos, {name=source,
|
||||
param2=LIQUID_MAX})
|
||||
else
|
||||
minetest.add_node(pos, {name=flowing,
|
||||
param2=fullness})
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if pointing to a buildable node
|
||||
local fullness = tonumber(itemstack:get_metadata())
|
||||
if not fullness then fullness = LIQUID_MAX end
|
||||
|
||||
if ndef and ndef.buildable_to then
|
||||
-- buildable; replace the node
|
||||
place_liquid(pointed_thing.under, node,
|
||||
source, flowing, fullness)
|
||||
else
|
||||
-- not buildable to; place the liquid above
|
||||
-- check if the node above can be replaced
|
||||
local node = minetest.get_node_or_nil(pointed_thing.above)
|
||||
if node and minetest.registered_nodes[node.name].buildable_to then
|
||||
place_liquid(pointed_thing.above,
|
||||
node, source,
|
||||
flowing, fullness)
|
||||
else
|
||||
-- do not remove the bucket with the liquid
|
||||
return
|
||||
end
|
||||
end
|
||||
return {name="bucket:bucket_empty"}
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_craftitem("bucket:bucket_empty", {
|
||||
description = "Empty Bucket",
|
||||
inventory_image = "bucket.png",
|
||||
stack_max = 1,
|
||||
liquids_pointable = true,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
-- Must be pointing to node
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
-- Check if pointing to a liquid source
|
||||
node = minetest.get_node(pointed_thing.under)
|
||||
liquiddef = bucket.liquids[node.name]
|
||||
if liquiddef ~= nil and liquiddef.itemname ~= nil and
|
||||
(node.name == liquiddef.source or
|
||||
(node.name == liquiddef.flowing and
|
||||
minetest.setting_getbool("liquid_finite"))) then
|
||||
if check_protection(pointed_thing.under,
|
||||
user:get_player_name(),
|
||||
"take ".. node.name) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.add_node(pointed_thing.under, {name="air"})
|
||||
|
||||
if node.name == liquiddef.source then
|
||||
node.param2 = LIQUID_MAX
|
||||
end
|
||||
return ItemStack({name = liquiddef.itemname,
|
||||
metadata = tostring(node.param2)})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
bucket.register_liquid(
|
||||
"default:water_source",
|
||||
"default:water_flowing",
|
||||
"bucket:bucket_water",
|
||||
"bucket_water.png",
|
||||
"Water Bucket"
|
||||
)
|
||||
|
||||
bucket.register_liquid(
|
||||
"default:lava_source",
|
||||
"default:lava_flowing",
|
||||
"bucket:bucket_lava",
|
||||
"bucket_lava.png",
|
||||
"Lava Bucket"
|
||||
)
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "bucket:bucket_lava",
|
||||
burntime = 60,
|
||||
replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}},
|
||||
})
|
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 288 B |