updated protector and bees, added awards and bergsee
|
@ -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,423 @@
|
|||
-- AWARDS
|
||||
-- by Rubenwardy, CC-BY-SA
|
||||
-------------------------------------------------------
|
||||
-- this is api function file
|
||||
-------------------------------------------------------
|
||||
|
||||
-- The global award namespace
|
||||
awards = {}
|
||||
|
||||
-- Table Save Load Functions
|
||||
function awards.save()
|
||||
local file = io.open(minetest.get_worldpath().."/awards.txt", "w")
|
||||
if file then
|
||||
file:write(minetest.serialize(awards.players))
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
function awards.load()
|
||||
local file = io.open(minetest.get_worldpath().."/awards.txt", "r")
|
||||
if file then
|
||||
local table = minetest.deserialize(file:read("*all"))
|
||||
if type(table) == "table" then
|
||||
return table
|
||||
end
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
awards.players = awards.load()
|
||||
function awards.player(name)
|
||||
return awards.players[name]
|
||||
end
|
||||
|
||||
-- A table of award definitions
|
||||
awards.def = {}
|
||||
|
||||
function awards.tbv(tb,value,default)
|
||||
if not default then
|
||||
default = {}
|
||||
end
|
||||
if not tb or type(tb) ~= "table" then
|
||||
if not value then
|
||||
value = "[NULL]"
|
||||
end
|
||||
minetest.log("error", "awards.tbv - table "..dump(value).." is null, or not a table! Dump: "..dump(tb))
|
||||
return
|
||||
end
|
||||
if not value then
|
||||
error("[ERROR] awards.tbv was not used correctly!\n"..
|
||||
"Value: '"..dump(value).."'\n"..
|
||||
"Dump:"..dump(tb))
|
||||
return
|
||||
end
|
||||
if not tb[value] then
|
||||
tb[value] = default
|
||||
end
|
||||
end
|
||||
|
||||
function awards.assertPlayer(playern)
|
||||
awards.tbv(awards.players, playern)
|
||||
awards.tbv(awards.players[playern], "name", playern)
|
||||
awards.tbv(awards.players[playern], "unlocked")
|
||||
awards.tbv(awards.players[playern], "place")
|
||||
awards.tbv(awards.players[playern], "count")
|
||||
awards.tbv(awards.players[playern], "deaths", 0)
|
||||
awards.tbv(awards.players[playern], "joins", 0)
|
||||
awards.tbv(awards.players[playern], "chats", 0)
|
||||
end
|
||||
|
||||
-- Load files
|
||||
dofile(minetest.get_modpath("awards").."/triggers.lua")
|
||||
dofile(minetest.get_modpath("awards").."/config.txt")
|
||||
|
||||
-- API Functions
|
||||
function awards._additional_triggers(name, data_table)
|
||||
-- To add triggers in another mod, you should override this function
|
||||
-- If the code can't handle the trigger passed, then call the last value of _additional_triggers
|
||||
--[[
|
||||
local add_trig = awards._additional_triggers
|
||||
awards._additional_triggers = function(name, data_table)
|
||||
if data_table.trigger.type == "trigger" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onTrigger,tmp)
|
||||
elseif data_table.trigger.type == "trigger2" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onTrigger2,tmp)
|
||||
else
|
||||
add_trig(name, data_table)
|
||||
end
|
||||
end
|
||||
]]--
|
||||
end
|
||||
function awards.register_achievement(name,data_table)
|
||||
-- see if a trigger is defined in the achievement definition
|
||||
if data_table.trigger and data_table.trigger.type then
|
||||
if data_table.trigger.type == "dig" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onDig,tmp)
|
||||
elseif data_table.trigger.type == "place" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onPlace,tmp)
|
||||
elseif data_table.trigger.type == "death" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onDeath,tmp)
|
||||
elseif data_table.trigger.type == "chat" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onChat,tmp)
|
||||
elseif data_table.trigger.type == "join" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onJoin,tmp)
|
||||
else
|
||||
awards._additional_triggers(name, data_table)
|
||||
end
|
||||
end
|
||||
|
||||
-- check icon, background and custom_announce data
|
||||
if data_table.icon == nil or data_table.icon == "" then
|
||||
data_table.icon = "unknown.png"
|
||||
end
|
||||
if data_table.background == nil or data_table.background == "" then
|
||||
data_table.background = "bg_default.png"
|
||||
end
|
||||
if data_table.custom_announce == nil or data_table.custom_announce == "" then
|
||||
data_table.custom_announce = "Achievement Unlocked:"
|
||||
end
|
||||
|
||||
-- add the achievement to the definition table
|
||||
data_table.name = name
|
||||
awards.def[name] = data_table
|
||||
end
|
||||
|
||||
-- run a function when a node is dug
|
||||
function awards.register_onDig(func)
|
||||
table.insert(awards.onDig,func)
|
||||
end
|
||||
|
||||
-- run a function when a node is placed
|
||||
function awards.register_onPlace(func)
|
||||
table.insert(awards.onPlace,func)
|
||||
end
|
||||
|
||||
-- run a function when a player dies
|
||||
function awards.register_onDeath(func)
|
||||
table.insert(awards.onDeath,func)
|
||||
end
|
||||
|
||||
-- run a function when a player chats
|
||||
function awards.register_onChat(func)
|
||||
table.insert(awards.onChat,func)
|
||||
end
|
||||
|
||||
-- run a function when a player joins
|
||||
function awards.register_onJoin(func)
|
||||
table.insert(awards.onJoin,func)
|
||||
end
|
||||
|
||||
-- This function is called whenever a target condition is met.
|
||||
-- It checks if a player already has that achievement, and if they do not,
|
||||
-- it gives it to them
|
||||
----------------------------------------------
|
||||
--awards.give_achievement(name,award)
|
||||
-- name - the name of the player
|
||||
-- award - the name of the award to give
|
||||
function awards.give_achievement(name,award)
|
||||
-- Access Player Data
|
||||
local data = awards.players[name]
|
||||
|
||||
-- Perform checks
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
if not awards.def[award] then
|
||||
return
|
||||
end
|
||||
awards.tbv(data,"unlocked")
|
||||
|
||||
-- check to see if the player does not already have that achievement
|
||||
if not data.unlocked[award] or data.unlocked[award]~=award then
|
||||
-- Set award flag
|
||||
data.unlocked[award]=award
|
||||
|
||||
-- Get data from definition tables
|
||||
local title = award
|
||||
local desc = ""
|
||||
local background = ""
|
||||
local icon = ""
|
||||
local custom_announce = ""
|
||||
if awards.def[award].title then
|
||||
title = awards.def[award].title
|
||||
end
|
||||
if awards.def[award].custom_announce then
|
||||
custom_announce = awards.def[award].custom_announce
|
||||
end
|
||||
if awards.def[award].background then
|
||||
background = awards.def[award].background
|
||||
end
|
||||
if awards.def[award].icon then
|
||||
icon = awards.def[award].icon
|
||||
end
|
||||
if awards.def[award] and awards.def[award].description then
|
||||
desc = awards.def[award].description
|
||||
end
|
||||
|
||||
-- send the won award message to the player
|
||||
if Use_Formspec == true then
|
||||
-- use a formspec to send it
|
||||
minetest.show_formspec(name, "achievements:unlocked", "size[4,2]"..
|
||||
"image_button_exit[0,0;4,2;"..background..";close1; ]"..
|
||||
"image_button_exit[0.2,0.8;1,1;"..icon..";close2; ]"..
|
||||
"label[1.1,1;"..title.."]"..
|
||||
"label[0.3,0.1;"..custom_announce.."]")
|
||||
else
|
||||
-- use the chat console to send it
|
||||
minetest.chat_send_player(name, "Achievement Unlocked: "..title)
|
||||
if desc~="" then
|
||||
minetest.chat_send_player(name, desc)
|
||||
end
|
||||
end
|
||||
|
||||
-- record this in the log
|
||||
minetest.log("action", name.." has unlocked award "..title)
|
||||
|
||||
-- save playertable
|
||||
awards.save()
|
||||
end
|
||||
end
|
||||
|
||||
-- List a player's achievements
|
||||
minetest.register_chatcommand("list_awards", {
|
||||
params = "obsolete",
|
||||
description = "list_awards: obsolete. Use /awards",
|
||||
func = function(name, param)
|
||||
minetest.chat_send_player(name, "This command has been made obsolete. Use /awards instead.")
|
||||
awards.showto(name, name, nil, false)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("awards", {
|
||||
params = "",
|
||||
description = "awards: list awards",
|
||||
func = function(name, param)
|
||||
awards.showto(name, name, nil, false)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("cawards", {
|
||||
params = "",
|
||||
description = "awards: list awards in chat",
|
||||
func = function(name, param)
|
||||
awards.showto(name, name, nil, true)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("awd", {
|
||||
params = "award name",
|
||||
description = "awd: Details of awd gotten",
|
||||
func = function(name, param)
|
||||
local def = awards.def[param]
|
||||
if def then
|
||||
minetest.chat_send_player(name,def.title..": "..def.description)
|
||||
else
|
||||
minetest.chat_send_player(name,"Award not found.")
|
||||
end
|
||||
end
|
||||
})
|
||||
--[[minetest.register_chatcommand("gawd", {
|
||||
params = "award name",
|
||||
description = "gawd: give award to self",
|
||||
func = function(name, param)
|
||||
awards.give_achievement(name,param)
|
||||
end
|
||||
})]]--
|
||||
|
||||
function awards._order_awards(name)
|
||||
local done = {}
|
||||
local retval = {}
|
||||
local player = awards.player(name)
|
||||
if player and player.unlocked then
|
||||
for _,got in pairs(player.unlocked) do
|
||||
done[got] = true
|
||||
table.insert(retval,{name=got,got=true})
|
||||
end
|
||||
end
|
||||
for _,def in pairs(awards.def) do
|
||||
if not done[def.name] then
|
||||
table.insert(retval,{name=def.name,got=false})
|
||||
end
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
function awards.showto(name, to, sid, text)
|
||||
if name == "" or name == nil then
|
||||
name = to
|
||||
end
|
||||
if text then
|
||||
if not awards.players[name] or not awards.players[name].unlocked then
|
||||
minetest.chat_send_player(to, "You have not unlocked any awards")
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(to, name.."'s awards:")
|
||||
|
||||
for _, str in pairs(awards.players[name].unlocked) do
|
||||
local def = awards.def[str]
|
||||
if def and def.title then
|
||||
if def.description then
|
||||
minetest.chat_send_player(to, def.title..": "..def.description)
|
||||
else
|
||||
minetest.chat_send_player(to, def.title)
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(to, str)
|
||||
end
|
||||
end
|
||||
else
|
||||
if sid == nil or sid < 1 then
|
||||
sid = 1
|
||||
end
|
||||
local formspec = "size[11,5]"
|
||||
local listofawards = awards._order_awards(name)
|
||||
|
||||
-- Sidebar
|
||||
if sid then
|
||||
local item = listofawards[sid+0]
|
||||
local def = awards.def[item.name]
|
||||
if def and def.secret and not item.got then
|
||||
formspec = formspec .. "label[1,2.75;Secret Award]"..
|
||||
"image[1,0;3,3;unknown.png]"
|
||||
if def and def.description then
|
||||
formspec = formspec .. "label[0,3.25;Unlock this award to find out what it is]"
|
||||
end
|
||||
else
|
||||
local title = item.name
|
||||
if def and def.title then
|
||||
title = def.title
|
||||
end
|
||||
local status = ""
|
||||
if item.got then
|
||||
status = " (got)"
|
||||
end
|
||||
if def and def.icon then
|
||||
icon = def.icon
|
||||
end
|
||||
formspec = formspec .. "label[1,2.75;"..title..status.."]"..
|
||||
"image[1,0;3,3;"..icon.."]"
|
||||
if def and def.description then
|
||||
formspec = formspec .. "label[0,3.25;"..def.description.."]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Create list box
|
||||
formspec = formspec .. "textlist[4.75,0;6,5;awards;"
|
||||
local first = true
|
||||
for _,award in pairs(listofawards) do
|
||||
if not first then
|
||||
formspec = formspec .. ","
|
||||
end
|
||||
first = false
|
||||
local def = awards.def[award.name]
|
||||
|
||||
if def and def.secret and not award.got then
|
||||
formspec = formspec .. "#ACACACSecret Award"
|
||||
else
|
||||
local title = award.name
|
||||
if def and def.title then
|
||||
title = def.title
|
||||
end
|
||||
if award.got then
|
||||
formspec = formspec .. minetest.formspec_escape(title)
|
||||
else
|
||||
formspec = formspec .. "#ACACAC".. minetest.formspec_escape(title)
|
||||
end
|
||||
end
|
||||
end
|
||||
formspec = formspec .. ";"..sid.."]"
|
||||
|
||||
-- Show formspec to user
|
||||
minetest.show_formspec(to,"awards:awards",formspec)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname~="awards:awards" then
|
||||
return false
|
||||
end
|
||||
if fields.quit then
|
||||
return true
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
if fields.awards then
|
||||
local event = minetest.explode_textlist_event(fields.awards)
|
||||
if event.type == "CHG" then
|
||||
awards.showto(name,name,event.index,false)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- AWARDS
|
||||
-- by Rubenwardy, CC-BY-SA
|
||||
-------------------------------------------------------
|
||||
-- this is the configuration file for the awards mod
|
||||
-------------------------------------------------------
|
||||
|
||||
Use_Formspec = true
|
||||
--Use a graphical display for unlocking achievements. (Possible values: true | false)
|
|
@ -0,0 +1,168 @@
|
|||
-- AWARDS
|
||||
-- by Rubenwardy, CC-BY-SA
|
||||
-------------------------------------------------------
|
||||
-- this is the init file for the award mod
|
||||
-------------------------------------------------------
|
||||
|
||||
local S
|
||||
if (intllib) then
|
||||
dofile(minetest.get_modpath("intllib").."/intllib.lua")
|
||||
S = intllib.Getter(minetest.get_current_modname())
|
||||
else
|
||||
S = function ( s ) return s end
|
||||
end
|
||||
|
||||
dofile(minetest.get_modpath("awards").."/api.lua")
|
||||
|
||||
-- Light it up
|
||||
awards.register_achievement("award_lightitup",{
|
||||
title = S("Light It Up"),
|
||||
description = S("Place 100 torches"),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "default:torch",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Lumber Jack
|
||||
awards.register_achievement("award_lumberjack",{
|
||||
title = S("Lumber Jack"),
|
||||
description = S("Dig 100 tree blocks"),
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:tree",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Found some Mese!
|
||||
awards.register_achievement("award_mesefind",{
|
||||
title = S("First Mese Find"),
|
||||
description = S("Found some Mese!"),
|
||||
icon = "mese.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:mese",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- Found a Nyan cat!
|
||||
awards.register_achievement("award_nyanfind",{
|
||||
title = S("OMG, Nyan Cat!"),
|
||||
description = S("Find a nyan cat"),
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:nyancat",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- Just entered the mine
|
||||
awards.register_achievement("award_mine1",{
|
||||
title = S("Entering the mine"),
|
||||
description = S("You have dug 10 stone blocks"),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 10
|
||||
}
|
||||
})
|
||||
|
||||
-- Mini Miner
|
||||
awards.register_achievement("award_mine2",{
|
||||
title = S("Mini Miner"),
|
||||
description = S("You have dug 100 stone blocks"),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Hardened Miner
|
||||
awards.register_achievement("award_mine3",{
|
||||
title = S("Hardened Miner"),
|
||||
description = S("You have dug 1000 stone blocks"),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- Master Miner
|
||||
awards.register_achievement("award_mine4",{
|
||||
title = S("Master Miner"),
|
||||
description = S("You have dug 10000 stone blocks"),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 10000
|
||||
}
|
||||
})
|
||||
|
||||
-- First Death
|
||||
awards.register_achievement("award_death1",{
|
||||
title = S("First Death"),
|
||||
description = S("You have more lives than a cat!"),
|
||||
trigger = {
|
||||
type = "death",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- Burned to death
|
||||
awards.register_achievement("award_burn",{
|
||||
title = S("You're a witch!"),
|
||||
description = S("Burn to death in a fire")
|
||||
})
|
||||
|
||||
-- 1 sentence
|
||||
awards.register_achievement("award_chat1",{
|
||||
title = S("First Word"),
|
||||
description = S("Use the chat to talk to players"),
|
||||
trigger = {
|
||||
type = "chat",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Join
|
||||
awards.register_achievement("award_join1",{
|
||||
title = S("Welcome!"),
|
||||
description = S("Connect to the server"),
|
||||
trigger = {
|
||||
type = "join",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
awards.register_achievement("award_join2",{
|
||||
title = S("Frequent Visitor"),
|
||||
description = S("Connect to the server 50 times"),
|
||||
trigger = {
|
||||
type = "join",
|
||||
target = 50
|
||||
},
|
||||
secret = true
|
||||
})
|
||||
|
||||
awards.register_onDeath(function(player,data)
|
||||
local pos = player:getpos()
|
||||
if pos and minetest.find_node_near(pos, 1, "fire:basic_flame") ~= nil then
|
||||
return "award_burn"
|
||||
end
|
||||
return nil
|
||||
end)
|
|
@ -0,0 +1,52 @@
|
|||
Awards
|
||||
------
|
||||
|
||||
by Andrew "Rubenwardy" Ward, CC-BY-SA.
|
||||
|
||||
This mod adds achievements to Minetest.
|
||||
|
||||
|
||||
Code Reference
|
||||
--------------
|
||||
|
||||
The API
|
||||
=======
|
||||
* awards.register_achievement(name,data_table)
|
||||
* name
|
||||
* desciption
|
||||
* sound [optional]
|
||||
* image [optional]
|
||||
* trigger [optional] [table]
|
||||
* type - "dig", "place", "death", "chat" or "join"
|
||||
* (for dig/place type) node - the nodes name
|
||||
* (for all types) target - how many to dig / place
|
||||
* secret [optional] - if true, then player needs to unlock to find out what it is.
|
||||
* awards.give_achievement(name,award)
|
||||
* -- gives an award to a player
|
||||
* awards.register_onDig(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onPlace(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onDeath(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onChat(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onJoin(func(player,data))
|
||||
* -- return award name or null
|
||||
|
||||
|
||||
Player Data
|
||||
===========
|
||||
|
||||
A list of data referenced/hashed by the player's name.
|
||||
* player name
|
||||
* name [string]
|
||||
* count [table] - dig counter
|
||||
* modname [table]
|
||||
* itemname [int]
|
||||
* place [table] - place counter
|
||||
* modname [table]
|
||||
* itemname [int]
|
||||
* deaths
|
||||
* chats
|
||||
* joins
|
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 322 B |
|
@ -0,0 +1,229 @@
|
|||
-- AWARDS
|
||||
-- by Rubenwardy, CC-BY-SA
|
||||
-------------------------------------------------------
|
||||
-- this is the trigger handler file for the awards mod
|
||||
-------------------------------------------------------
|
||||
|
||||
-- Function and table holders for Triggers
|
||||
awards.onDig = {}
|
||||
awards.onPlace = {}
|
||||
awards.onChat = {}
|
||||
awards.onDeath = {}
|
||||
awards.onJoin = {}
|
||||
|
||||
-- Trigger Handles
|
||||
minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
if not digger or not pos or not oldnode then
|
||||
return
|
||||
end
|
||||
local nodedug = string.split(oldnode.name, ":")
|
||||
if #nodedug ~= 2 then
|
||||
minetest.log("error","Awards mod: "..oldnode.name.." is in wrong format!")
|
||||
return
|
||||
end
|
||||
local mod = nodedug[1]
|
||||
local item = nodedug[2]
|
||||
local playern = digger:get_player_name()
|
||||
|
||||
if (not playern or not nodedug or not mod or not item) then
|
||||
return
|
||||
end
|
||||
awards.assertPlayer(playern)
|
||||
awards.tbv(awards.players[playern].count, mod)
|
||||
awards.tbv(awards.players[playern].count[mod], item, 0)
|
||||
|
||||
-- Increment counter
|
||||
awards.players[playern].count[mod][item]=awards.players[playern].count[mod][item] + 1
|
||||
|
||||
-- Run callbacks and triggers
|
||||
local player=digger
|
||||
local data=awards.players[playern]
|
||||
for i=1,# awards.onDig do
|
||||
local res = nil
|
||||
if type(awards.onDig[i]) == "function" then
|
||||
-- Run trigger callback
|
||||
res = awards.onDig[i](player,data)
|
||||
elseif type(awards.onDig[i]) == "table" then
|
||||
-- Handle table trigger
|
||||
if not awards.onDig[i].node or not awards.onDig[i].target or not awards.onDig[i].award then
|
||||
-- table running failed!
|
||||
print("[ERROR] awards - onDig trigger "..i.." is invalid!")
|
||||
else
|
||||
-- run the table
|
||||
local tnodedug = string.split(awards.onDig[i].node, ":")
|
||||
local tmod=tnodedug[1]
|
||||
local titem=tnodedug[2]
|
||||
if tmod==nil or titem==nil or not data.count[tmod] or not data.count[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.count[tmod][titem] > awards.onDig[i].target-1 then
|
||||
res=awards.onDig[i].award
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if res then
|
||||
awards.give_achievement(playern,res)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_placenode(function(pos,node,digger)
|
||||
if not digger or not pos or not node or not digger:get_player_name() or digger:get_player_name()=="" then
|
||||
return
|
||||
end
|
||||
local nodedug = string.split(node.name, ":")
|
||||
if #nodedug ~= 2 then
|
||||
minetest.log("error","Awards mod: "..node.name.." is in wrong format!")
|
||||
return
|
||||
end
|
||||
local mod=nodedug[1]
|
||||
local item=nodedug[2]
|
||||
local playern = digger:get_player_name()
|
||||
|
||||
-- Run checks
|
||||
if (not playern or not nodedug or not mod or not item) then
|
||||
return
|
||||
end
|
||||
awards.assertPlayer(playern)
|
||||
awards.tbv(awards.players[playern].place, mod)
|
||||
awards.tbv(awards.players[playern].place[mod], item, 0)
|
||||
|
||||
-- Increment counter
|
||||
awards.players[playern].place[mod][item] = awards.players[playern].place[mod][item] + 1
|
||||
|
||||
-- Run callbacks and triggers
|
||||
local player = digger
|
||||
local data = awards.players[playern]
|
||||
for i=1,# awards.onPlace do
|
||||
local res = nil
|
||||
if type(awards.onPlace[i]) == "function" then
|
||||
-- Run trigger callback
|
||||
res = awards.onPlace[i](player,data)
|
||||
elseif type(awards.onPlace[i]) == "table" then
|
||||
-- Handle table trigger
|
||||
if not awards.onPlace[i].node or not awards.onPlace[i].target or not awards.onPlace[i].award then
|
||||
print("[ERROR] awards - onPlace trigger "..i.." is invalid!")
|
||||
else
|
||||
-- run the table
|
||||
local tnodedug = string.split(awards.onPlace[i].node, ":")
|
||||
local tmod = tnodedug[1]
|
||||
local titem = tnodedug[2]
|
||||
if tmod==nil or titem==nil or not data.place[tmod] or not data.place[tmod][titem] then
|
||||
-- table running failed!
|
||||
elseif data.place[tmod][titem] > awards.onPlace[i].target-1 then
|
||||
res = awards.onPlace[i].award
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if res then
|
||||
awards.give_achievement(playern,res)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
-- Run checks
|
||||
local name = player:get_player_name()
|
||||
if not player or not name or name=="" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get player
|
||||
awards.assertPlayer(name)
|
||||
local data = awards.players[name]
|
||||
|
||||
-- Increment counter
|
||||
data.deaths = data.deaths + 1
|
||||
|
||||
-- Run callbacks and triggers
|
||||
for _,trigger in pairs(awards.onDeath) do
|
||||
local res = nil
|
||||
if type(trigger) == "function" then
|
||||
res = trigger(player,data)
|
||||
elseif type(trigger) == "table" then
|
||||
if trigger.target and trigger.award then
|
||||
if data.deaths and data.deaths >= trigger.target then
|
||||
res = trigger.award
|
||||
end
|
||||
end
|
||||
end
|
||||
if res ~= nil then
|
||||
awards.give_achievement(name,res)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
-- Run checks
|
||||
local name = player:get_player_name()
|
||||
if not player or not name or name=="" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get player
|
||||
awards.assertPlayer(name)
|
||||
local data = awards.players[name]
|
||||
|
||||
-- Increment counter
|
||||
data.joins = data.joins + 1
|
||||
|
||||
-- Run callbacks and triggers
|
||||
for _,trigger in pairs(awards.onJoin) do
|
||||
local res = nil
|
||||
if type(trigger) == "function" then
|
||||
res = trigger(player,data)
|
||||
elseif type(trigger) == "table" then
|
||||
if trigger.target and trigger.award then
|
||||
if data.joins and data.joins >= trigger.target then
|
||||
res = trigger.award
|
||||
end
|
||||
end
|
||||
end
|
||||
if res ~= nil then
|
||||
awards.give_achievement(name,res)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
-- Run checks
|
||||
local idx = string.find(message,"/")
|
||||
if not name or (idx ~= nil and idx <= 1) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get player
|
||||
awards.assertPlayer(name)
|
||||
local data = awards.players[name]
|
||||
local player = minetest.get_player_by_name(name)
|
||||
|
||||
-- Increment counter
|
||||
data.chats = data.chats + 1
|
||||
|
||||
-- Run callbacks and triggers
|
||||
for _,trigger in pairs(awards.onChat) do
|
||||
local res = nil
|
||||
if type(trigger) == "function" then
|
||||
res = trigger(player,data)
|
||||
elseif type(trigger) == "table" then
|
||||
if trigger.target and trigger.award then
|
||||
if data.chats and data.chats >= trigger.target then
|
||||
res = trigger.award
|
||||
end
|
||||
end
|
||||
end
|
||||
if res ~= nil then
|
||||
awards.give_achievement(name,res)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_newplayer(function(player)
|
||||
local playern = player:get_player_name()
|
||||
awards.assertPlayer(playern)
|
||||
end)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
awards.save()
|
||||
end)
|
|
@ -1,358 +1,425 @@
|
|||
--Bees mod by bas080
|
||||
--Bees
|
||||
------
|
||||
--Author Bas080
|
||||
--Version 2.0
|
||||
--License WTFPL
|
||||
|
||||
--[[TODO
|
||||
Smoker
|
||||
Grafting Tool
|
||||
|
||||
smoker maybe
|
||||
Spreading bee colonies
|
||||
x Grafting Tool - to remove queen bees from wild hives
|
||||
x Make flowers reproduce when near a hive
|
||||
x Add formspec to twild hive when using grafting tool
|
||||
]]
|
||||
local sound = {}
|
||||
local particles = {}
|
||||
--VARIABLES
|
||||
local sound = {}
|
||||
local particles = {}
|
||||
local bees = {}
|
||||
local formspecs = {}
|
||||
|
||||
--nodes
|
||||
minetest.register_node("bees:bees", {
|
||||
description = "Wild Bees",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
{
|
||||
name="bees_strip.png",
|
||||
animation={type="vertical_frames", aspect_w=16,aspect_h=16, length=2.0}
|
||||
}
|
||||
},
|
||||
damage_per_second = 1,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
pointable = false,
|
||||
on_punch = function(pos, node, puncher)
|
||||
local health = puncher:get_hp()
|
||||
puncher:set_hp(health-2)
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
spawn_bees(pos)
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
remove_bees(pos)
|
||||
end,
|
||||
})
|
||||
--FUNCTIONS
|
||||
function formspecs.hive_wild(pos, grafting)
|
||||
local spos = pos.x .. ',' .. pos.y .. ',' ..pos.z
|
||||
local formspec =
|
||||
'size[8,9]'..
|
||||
'list[nodemeta:'.. spos .. ';combs;1.5,3;5,1;]'..
|
||||
'list[current_player;main;0,5;8,4;]'
|
||||
if grafting then
|
||||
formspec = formspec..'list[nodemeta:'.. spos .. ';queen;3.5,1;1,1;]'
|
||||
end
|
||||
return formspec
|
||||
end
|
||||
|
||||
minetest.register_node("bees:hive", {
|
||||
description = "Wild Bee Hive",
|
||||
tile_images = {"bees_hive_wild.png","bees_hive_wild.png","bees_hive_wild.png", "bees_hive_wild.png", "bees_hive_wild_bottom.png"}, --Neuromancer's base texture
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = 'wallmounted',
|
||||
drop = {
|
||||
max_items = 6,
|
||||
items = {
|
||||
{ items = {'bees:honey_comb'} },
|
||||
{ items = {'bees:honey_comb'}, rarity = 2},
|
||||
{ items = {'bees:honey_comb'}, rarity = 5},
|
||||
{ items = {'bees:queen'}, rarity = 10 }
|
||||
}
|
||||
},
|
||||
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,attached_node=1},
|
||||
node_box = { --VanessaE's wild hive nodebox contribution
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.250000,-0.500000,-0.250000,0.250000,0.375000,0.250000}, --NodeBox 2
|
||||
{-0.312500,-0.375000,-0.312500,0.312500,0.250000,0.312500}, --NodeBox 4
|
||||
{-0.375000,-0.250000,-0.375000,0.375000,0.125000,0.375000}, --NodeBox 5
|
||||
{-0.062500,-0.500000,-0.062500,0.062500,0.500000,0.062500}, --NodeBox 6
|
||||
}
|
||||
},
|
||||
on_construct = function(pos)
|
||||
spawn_bees(pos)
|
||||
minetest.get_node(pos).param2 = 0
|
||||
end,
|
||||
on_punch = function(pos, node, puncher)
|
||||
local health = puncher:get_hp()
|
||||
puncher:set_hp(health-2)
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, user)
|
||||
local wielded if user:get_wielded_item() ~= nil then wielded = user:get_wielded_item() else return end
|
||||
if 'bees:grafting_tool' == wielded:get_name() then
|
||||
local inv = user:get_inventory()
|
||||
if inv then
|
||||
inv:add_item("main", ItemStack("bees:queen"))
|
||||
end
|
||||
function formspecs.hive_artificial(pos)
|
||||
local spos = pos.x..','..pos.y..','..pos.z
|
||||
local formspec =
|
||||
'size[8,9]'..
|
||||
'list[nodemeta:'..spos..';queen;3.5,1;1,1;]'..
|
||||
'list[nodemeta:'..spos..';frames;0,3;8,1;]'..
|
||||
'list[current_player;main;0,5;8,4;]'
|
||||
return formspec
|
||||
end
|
||||
|
||||
function bees.polinate_flower(pos, flower)
|
||||
local spawn_pos = { x=pos.x+math.random(-3,3) , y=pos.y+math.random(-3,3) , z=pos.z+math.random(-3,3) }
|
||||
local floor_pos = { x=spawn_pos.x , y=spawn_pos.y-1 , z=spawn_pos.z }
|
||||
local spawn = minetest.get_node(spawn_pos).name
|
||||
local floor = minetest.get_node(floor_pos).name
|
||||
if floor == 'default:dirt_with_grass' and spawn == 'air' then
|
||||
minetest.set_node(spawn_pos, {name=flower})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("bees:hive_artificial", {
|
||||
description = "Bee Hive",
|
||||
tiles = {"default_wood.png","default_wood.png","default_wood.png", "default_wood.png","default_wood.png","bees_hive_artificial.png"},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
|
||||
{-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
|
||||
{-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
|
||||
{-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
|
||||
{-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
|
||||
{1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
|
||||
}
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local tmr = minetest.get_node_timer(pos)
|
||||
tmr:start(10)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('inhabited','false')
|
||||
meta:set_string('infotext','Requires the Queen bee');
|
||||
end,
|
||||
})
|
||||
--NODES
|
||||
minetest.register_node('bees:bees', {
|
||||
description = 'Flying Bees',
|
||||
drawtype = 'plantlike',
|
||||
paramtype = 'light',
|
||||
tiles = {
|
||||
{
|
||||
name='bees_strip.png',
|
||||
animation={type='vertical_frames', aspect_w=16,aspect_h=16, length=2.0}
|
||||
}
|
||||
},
|
||||
damage_per_second = 1,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
pointable = false,
|
||||
on_punch = function(pos, node, puncher)
|
||||
local health = puncher:get_hp()
|
||||
puncher:set_hp(health-2)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("bees:hive_artificial_inhabited", {
|
||||
description = "Bee Hive",
|
||||
tiles = {"default_wood.png","default_wood.png","default_wood.png", "default_wood.png","default_wood.png","bees_hive_artificial.png"},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
|
||||
{-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
|
||||
{-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
|
||||
{-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
|
||||
{-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
|
||||
{1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
|
||||
}
|
||||
},
|
||||
drop = "bees:hive_artificial 1",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
--on_punch = candles.collect,
|
||||
on_timer = function(pos,elapsed)
|
||||
local rad = 10
|
||||
local minp = {x=pos.x-rad, y=pos.y-rad, z=pos.z-rad}
|
||||
local maxp = {x=pos.x+rad, y=pos.y+rad, z=pos.z+rad}
|
||||
local flower_in_area = minetest.find_nodes_in_area(minp, maxp, "group:flower")
|
||||
local flower_number = 0
|
||||
for i in ipairs(flower_in_area) do
|
||||
flower_number = flower_number + 1
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local honey = meta:get_int("honey")
|
||||
honey = honey + flower_number/10
|
||||
|
||||
if honey < 100 then
|
||||
meta:set_string('infotext',honey.."%");
|
||||
meta:set_int("honey", honey)
|
||||
local tmr = minetest.get_node_timer(pos)
|
||||
tmr:start(60)
|
||||
else
|
||||
meta:set_string('infotext',"100% - Time to harvest");
|
||||
meta:set_int("honey", 100)
|
||||
end
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
spawn_bees(pos)
|
||||
local tmr = minetest.get_node_timer(pos)
|
||||
tmr:start(60)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('inhabited','false')
|
||||
meta:set_int("honey", 0)
|
||||
meta:set_string('infotext','0%');
|
||||
end,
|
||||
on_punch = function(pos, node, puncher)
|
||||
local health = puncher:get_hp()
|
||||
puncher:set_hp(health-2)
|
||||
spawn_bees(pos)
|
||||
end,
|
||||
on_rightclick = function(pos, node, puncher)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local honey = meta:get_int("honey")
|
||||
if honey == 100 then
|
||||
for i=math.random(1,3), 0, -1 do
|
||||
local p = {x=pos.x+math.random()-0.5,y=pos.y+1,z=pos.z+math.random()-0.5}
|
||||
minetest.add_item(p, "bees:honey_comb")
|
||||
minetest.register_node('bees:hive_wild', {
|
||||
description = 'wild bee hive',
|
||||
tile_images = {'bees_hive_wild.png','bees_hive_wild.png','bees_hive_wild.png', 'bees_hive_wild.png', 'bees_hive_wild_bottom.png'}, --Neuromancer's base texture
|
||||
drawtype = 'nodebox',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'wallmounted',
|
||||
drop = {
|
||||
max_items = 6,
|
||||
items = {
|
||||
{ items = {'bees:honey_comb'}, rarity = 5}
|
||||
}
|
||||
},
|
||||
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,attached_node=1},
|
||||
node_box = { --VanessaE's wild hive nodebox contribution
|
||||
type = 'fixed',
|
||||
fixed = {
|
||||
{-0.250000,-0.500000,-0.250000,0.250000,0.375000,0.250000}, --NodeBox 2
|
||||
{-0.312500,-0.375000,-0.312500,0.312500,0.250000,0.312500}, --NodeBox 4
|
||||
{-0.375000,-0.250000,-0.375000,0.375000,0.125000,0.375000}, --NodeBox 5
|
||||
{-0.062500,-0.500000,-0.062500,0.062500,0.500000,0.062500}, --NodeBox 6
|
||||
}
|
||||
},
|
||||
on_timer = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local timer= minetest.get_node_timer(pos)
|
||||
local rad = 10
|
||||
local minp = {x=pos.x-rad, y=pos.y-rad, z=pos.z-rad}
|
||||
local maxp = {x=pos.x+rad, y=pos.y+rad, z=pos.z+rad}
|
||||
local flowers = minetest.find_nodes_in_area(minp, maxp, 'group:flower')
|
||||
if #flowers == 0 then
|
||||
inv:set_stack('queen', 1, '')
|
||||
meta:set_string('infotext', 'this colony died, not enough flowers in area')
|
||||
return
|
||||
end --not any flowers nearby The queen dies!
|
||||
if #flowers < 3 then return end --requires 2 or more flowers before can make honey
|
||||
local flower = flowers[math.random(#flowers)]
|
||||
bees.polinate_flower(flower, minetest.get_node(flower).name)
|
||||
local stacks = inv:get_list('combs')
|
||||
for k, v in pairs(stacks) do
|
||||
if inv:get_stack('combs', k):is_empty() then --then replace that with a full one and reset pro..
|
||||
inv:set_stack('combs',k,'bees:honey_comb')
|
||||
timer:start(1000/#flowers)
|
||||
return
|
||||
end
|
||||
end
|
||||
meta:set_int("honey", 0)
|
||||
meta:set_string('infotext',"0%");
|
||||
local tmr = minetest.get_node_timer(pos)
|
||||
tmr:start(60)
|
||||
end
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, user)
|
||||
local wielded if user:get_wielded_item() ~= nil then wielded = user:get_wielded_item() else return end
|
||||
if 'bees:grafting_tool' == wielded:get_name() then
|
||||
local inv = user:get_inventory()
|
||||
if inv then
|
||||
inv:add_item("main", ItemStack("bees:queen"))
|
||||
--what to do if all combs are filled
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
minetest.get_node(pos).param2 = 0
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(100+math.random(100))
|
||||
inv:set_size('queen', 1)
|
||||
inv:set_size('combs', 5)
|
||||
inv:set_stack('queen', 1, 'bees:queen')
|
||||
for i=1,math.random(3) do
|
||||
inv:set_stack('combs', i, 'bees:honey_comb')
|
||||
end
|
||||
end,
|
||||
on_punch = function(pos, node, puncher)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if inv:contains_item('queen','bees:queen') then
|
||||
local health = puncher:get_hp()
|
||||
puncher:set_hp(health-4)
|
||||
end
|
||||
end,
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, taker)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local timer= minetest.get_node_timer(pos)
|
||||
if listname == 'combs' and inv:contains_item('queen', 'bees:queen') then
|
||||
local health = taker:get_hp()
|
||||
timer:start(10)
|
||||
taker:set_hp(health-2)
|
||||
end
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, taker) --restart the colony by adding a queen
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
if not timer:is_started() then
|
||||
timer:start(10)
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if listname == 'queen' and stack:get_name() == 'bees:queen' then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
minetest.show_formspec(
|
||||
clicker:get_player_name(),
|
||||
'bees:hive_artificial',
|
||||
formspecs.hive_wild(pos, (itemstack:get_name() == 'bees:grafting_tool'))
|
||||
)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty('queen') and inv:is_empty('combs') then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, user)
|
||||
local wielded if user:get_wielded_item() ~= nil then wielded = user:get_wielded_item() else return end
|
||||
if 'bees:grafting_tool' == wielded:get_name() then
|
||||
local inv = user:get_inventory()
|
||||
if inv then
|
||||
inv:add_item('main', ItemStack('bees:queen'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
})
|
||||
|
||||
--abms
|
||||
--[[
|
||||
minetest.register_abm({ --for particles and sounds
|
||||
nodenames = {"bees:hive", "bees:bees", "bees:hive_artificial_inhabited"},
|
||||
interval = 1,
|
||||
chance = 6,
|
||||
action = function(pos, node, _, _)
|
||||
if math.random()<0.5 then
|
||||
local img = "bees_particle_bee.png"
|
||||
else
|
||||
local img = "bees_particle_bee_r.png"
|
||||
end
|
||||
sound["x"..pos.x.."y"..pos.y.."z"..pos.z] = minetest.sound_play({name="bees"},{pos=pos, max_hear_distance=8, gain=0.6})
|
||||
local p = {x=pos.x, y=pos.y+math.random()-0.5, z=pos.z}
|
||||
|
||||
end,
|
||||
})
|
||||
minetest.register_node('bees:hive_artificial', {
|
||||
description = 'Bee Hive',
|
||||
tiles = {'default_wood.png','default_wood.png','default_wood.png', 'default_wood.png','default_wood.png','bees_hive_artificial.png'},
|
||||
drawtype = 'nodebox',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'facedir',
|
||||
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
node_box = {
|
||||
type = 'fixed',
|
||||
fixed = {
|
||||
{-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
|
||||
{-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
|
||||
{-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
|
||||
{-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
|
||||
{-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
|
||||
{1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
|
||||
}
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('queen', 1)
|
||||
inv:set_size('frames', 8)
|
||||
meta:set_string('infotext','requires queen bee to function')
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
minetest.show_formspec(
|
||||
clicker:get_player_name(),
|
||||
'bees:hive_artificial',
|
||||
formspecs.hive_artificial(pos)
|
||||
)
|
||||
end,
|
||||
on_timer = function(pos,elapsed)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
if inv:contains_item('queen', 'bees:queen') then
|
||||
if inv:contains_item('frames', 'bees:frame_empty') then
|
||||
timer:start(30)
|
||||
local rad = 10
|
||||
local minp = {x=pos.x-rad, y=pos.y-rad, z=pos.z-rad}
|
||||
local maxp = {x=pos.x+rad, y=pos.y+rad, z=pos.z+rad}
|
||||
local flowers = minetest.find_nodes_in_area(minp, maxp, 'group:flower')
|
||||
local progress = meta:get_int('progress')
|
||||
progress = progress + #flowers
|
||||
meta:set_int('progress', progress)
|
||||
if progress > 1000 then
|
||||
local flower = flowers[math.random(#flowers)]
|
||||
bees.polinate_flower(flower, minetest.get_node(flower).name)
|
||||
local stacks = inv:get_list('frames')
|
||||
for k, v in pairs(stacks) do
|
||||
if inv:get_stack('frames', k):get_name() == 'bees:frame_empty' then --then replace that with a full one and reset pro..
|
||||
meta:set_int('progress', 0)
|
||||
inv:set_stack('frames',k,'bees:frame_full')
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
meta:set_string('infotext', 'progress: '..progress..'+'..#flowers..'/1000')
|
||||
end
|
||||
else
|
||||
meta:set_string('infotext', 'does not have empty frame(s)')
|
||||
timer:stop()
|
||||
end
|
||||
end
|
||||
end,
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
if listname == 'queen' then
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('infotext','requires queen bee to function')
|
||||
timer:stop()
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if from_list ~= to_list then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
if listname == 'queen' or listname == 'frames' then
|
||||
meta:set_string('queen', stack:get_name())
|
||||
meta:set_string('infotext','queen is inserted, now for the empty frames');
|
||||
if inv:contains_item('frames', 'bees:frame_empty') then
|
||||
timer:start(30)
|
||||
meta:set_string('infotext','bees are aclimating');
|
||||
end
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if listname == 'queen' then
|
||||
if stack:get_name():match('bees:queen*') then
|
||||
return 1
|
||||
end
|
||||
elseif listname == 'frames' then
|
||||
if stack:get_name() == ('bees:frame_empty') then
|
||||
return 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.add_particle(
|
||||
p,
|
||||
{x=(math.random()-0.5)*5,y=(math.random()-0.5)*5,z=(math.random()-0.5)*5},
|
||||
{x=math.random()-0.5,y=math.random()-0.5,z=math.random()-0.5},
|
||||
math.random(2,5),
|
||||
math.random(3),
|
||||
true,
|
||||
"bees_particle_bee.png"
|
||||
)
|
||||
--ABMS
|
||||
minetest.register_abm({ --spawn abm. This should be changed to a more realistic type of spawning
|
||||
nodenames = {'group:leaves'},
|
||||
neighbors = {''},
|
||||
interval = 1600,
|
||||
chance = 20,
|
||||
action = function(pos, node, _, _)
|
||||
local p = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
if minetest.get_node(p).walkable == false then return end
|
||||
if (minetest.find_node_near(p, 5, 'group:flora') ~= nil and minetest.find_node_near(p, 40, 'bees:hive_wild') == nil) then
|
||||
minetest.add_node(p, {name='bees:hive_wild'})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.add_particle(
|
||||
pos,
|
||||
velocity,
|
||||
acceleration,
|
||||
expirationtime,
|
||||
size,
|
||||
collisiondetection,
|
||||
texture,
|
||||
playername
|
||||
)
|
||||
]]
|
||||
function spawn_bees(pos)
|
||||
--[[local id = minetest.pos_to_string(pos)
|
||||
if particles[id] ~= nil then return end
|
||||
particles[id] = minetest.add_particlespawner(
|
||||
2,
|
||||
0,
|
||||
{x=pos.x-0.5,y=pos.y-0.5,z=pos.z-0.5}, {x=pos.x+0.5,y=pos.y+0.5,z=pos.z+0.5},
|
||||
{x=-2.5,y=-2.5,z=-2.5}, {x=2.5,y=2.5,z=2.5},
|
||||
{x=-0.5,y=-0.5,z=-0.5}, {x=0.5,y=0.5,z=0.5},
|
||||
2, 5,
|
||||
1, 3,
|
||||
true,
|
||||
"bees_particle_bee.png"
|
||||
)
|
||||
]]
|
||||
end
|
||||
minetest.register_abm({ --spawning bees around bee hive
|
||||
nodenames = {'bees:hive_wild', 'bees:hive_artificial'},
|
||||
neighbors = {'group:flowers', 'group:leaves'},
|
||||
interval = 30,
|
||||
chance = 4,
|
||||
action = function(pos, node, _, _)
|
||||
local p = {x=pos.x+math.random(-5,5), y=pos.y-math.random(0,3), z=pos.z+math.random(-5,5)}
|
||||
if minetest.get_node(p).name == 'air' then
|
||||
minetest.add_node(p, {name='bees:bees'})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
function remove_bees(pos)
|
||||
--[[local id = particles[minetest.pos_to_string(pos)]
|
||||
if id == nil then return end
|
||||
minetest.delete_particlespawner(id)
|
||||
]]
|
||||
end
|
||||
minetest.register_abm({ --remove bees
|
||||
nodenames = {'bees:bees'},
|
||||
interval = 30,
|
||||
chance = 5,
|
||||
action = function(pos, node, _, _)
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({ --spawn abm
|
||||
nodenames = {"group:leafdecay"},
|
||||
neighbors = {"default:apple"},
|
||||
interval = 1800,
|
||||
chance = 500,
|
||||
action = function(pos, node, _, _)
|
||||
local p = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
if minetest.get_node(p).walkable == false then return end
|
||||
if (minetest.find_node_near(p, 5, "group:flora") ~= nil and minetest.find_node_near(p, 20, "bees:hive") == nil) then
|
||||
minetest.add_node(p, {name="bees:hive"})
|
||||
end
|
||||
end,
|
||||
})
|
||||
--ITEMS
|
||||
minetest.register_craftitem('bees:frame_empty', {
|
||||
description = 'empty hive frame',
|
||||
inventory_image = 'bees_frame_empty.png',
|
||||
stack_max = 20,
|
||||
})
|
||||
|
||||
minetest.register_abm({ --spawning bees around bee hive
|
||||
nodenames = {"bees:hive"},
|
||||
interval = 10,
|
||||
chance = 2,
|
||||
action = function(pos, node, _, _)
|
||||
local p = {x=pos.x+math.random(-5,5), y=pos.y-math.random(0,3), z=pos.z+math.random(-5,5)}
|
||||
if minetest.get_node(p).name == "air" then
|
||||
minetest.add_node(p, {name="bees:bees"})
|
||||
end
|
||||
end,
|
||||
})
|
||||
minetest.register_craftitem('bees:frame_full', {
|
||||
description = 'filled hive frame',
|
||||
inventory_image = 'bees_frame_full.png',
|
||||
stack_max = 4,
|
||||
})
|
||||
|
||||
minetest.register_abm({ --remove bees
|
||||
nodenames = {"bees:bees"},
|
||||
interval = 60,
|
||||
chance = 4,
|
||||
action = function(pos, node, _, _)
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
})
|
||||
minetest.register_craftitem('bees:honey_comb', {
|
||||
description = 'Honey Comb',
|
||||
inventory_image = 'bees_comb.png',
|
||||
on_use = minetest.item_eat(2),
|
||||
stack_max = 8,
|
||||
})
|
||||
|
||||
--items
|
||||
minetest.register_craftitem("bees:honey_comb", {
|
||||
description = "Honey Comb",
|
||||
inventory_image = "bees_comb.png",
|
||||
on_use = minetest.item_eat(3),
|
||||
})
|
||||
minetest.register_craftitem('bees:honey_bottle', {
|
||||
description = 'Honey Bottle',
|
||||
inventory_image = 'bees_honey_bottle.png',
|
||||
on_use = minetest.item_eat(6),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("bees:honey_bottle", {
|
||||
description = "Honey Bottle",
|
||||
inventory_image = "bees_honey_bottle.png",
|
||||
on_use = minetest.item_eat(6),
|
||||
})
|
||||
minetest.register_craftitem('bees:queen', {
|
||||
description = 'Queen Bee',
|
||||
inventory_image = 'bees_particle_bee.png',
|
||||
stack_max = 1,
|
||||
})
|
||||
|
||||
minetest.register_craftitem("bees:queen", {
|
||||
description = "Queen Bee",
|
||||
inventory_image = "bees_particle_bee.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.under == nil then return end
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
local name = minetest.get_node(pointed_thing.under).name
|
||||
|
||||
if name == "bees:hive_artificial" then
|
||||
local facing = node.param2
|
||||
minetest.set_node(pointed_thing.under, {name = "bees:hive_artificial_inhabited", param2=facing})
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
})
|
||||
--CRAFTS
|
||||
minetest.register_craft({
|
||||
output = 'bees:honey_bottle',
|
||||
recipe = {
|
||||
{'bees:honey_comb'},
|
||||
{'vessels:glass_bottle'},
|
||||
}
|
||||
})
|
||||
|
||||
--crafts
|
||||
minetest.register_craft({
|
||||
output = 'bees:honey_bottle',
|
||||
recipe = {
|
||||
{'bees:honey_comb'},
|
||||
{'vessels:glass_bottle'},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'bees:hive_artificial',
|
||||
recipe = {
|
||||
{'group:wood','group:wood','group:wood'},
|
||||
{'group:wood','default:stick','group:wood'},
|
||||
{'group:wood','default:stick','group:wood'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'bees:hive_artificial',
|
||||
recipe = {
|
||||
{'group:wood','group:wood','group:wood'},
|
||||
{'group:wood','default:stick','group:wood'},
|
||||
{'group:wood','default:stick','group:wood'},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'bees:grafting_tool',
|
||||
recipe = {
|
||||
{'', '', 'default:steel_ingot'},
|
||||
{'', 'default:stick', ''},
|
||||
{'', '', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'bees:frame_empty',
|
||||
recipe = {
|
||||
{'default:wood', 'default:wood', 'default:wood'},
|
||||
{'default:stick', 'default:stick', 'default:stick'},
|
||||
{'default:stick', 'default:stick', 'default:stick'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_tool("bees:grafting_tool", {
|
||||
description = "Grafting Tool",
|
||||
inventory_image = "bees_grafting_tool.png",
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 3.0,
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
choppy = {times={[2]=3.00, [3]=2.00}, uses=10, maxlevel=1},
|
||||
},
|
||||
damage_groups = {fleshy=2},
|
||||
},
|
||||
})
|
||||
--TOOLS
|
||||
minetest.register_tool('bees:grafting_tool', {
|
||||
description = 'Grafting Tool',
|
||||
inventory_image = 'bees_grafting_tool.png',
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 3.0,
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
choppy = {times={[2]=3.00, [3]=2.00}, uses=10, maxlevel=1},
|
||||
},
|
||||
damage_groups = {fleshy=2},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'bees:grafting_tool',
|
||||
recipe = {
|
||||
{'', '', 'default:steel_ingot'},
|
||||
{'', 'default:stick', ''},
|
||||
{'', '', ''},
|
||||
}
|
||||
})
|
||||
--ALIASES
|
||||
minetest.register_alias('bees:hive', 'bees:hive_wild')
|
||||
minetest.register_alias('bees:hive_artificial_inhabited', 'bees:hive_artificial')
|
||||
print('[Mod]Bees Loaded!')
|
||||
|
|
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 658 B |
After Width: | Height: | Size: 543 B |
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 477 B |
|
@ -0,0 +1,4 @@
|
|||
Mod for Minetest and Freeminer
|
||||
|
||||
This mod adds lakes above sealevel.
|
||||
Licence of code: GPLv3 or later.
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,176 @@
|
|||
--[[
|
||||
1. We choose a random position in the same way plants are placed. That's the root for our lake.
|
||||
2. From there we go lx in the x direction and lz in the z direction. That gives us a rectangle.
|
||||
3. We check the sides of the rectangle for air and itterate down until the rectangle is closed.
|
||||
4. Now we repeat this itteration, but search for the opposite, not for solid nodes but for air.
|
||||
5. As soon as we found the lower limit, we check if the bottom is sealed. Now we have some jar.
|
||||
6. Now as we made sure no water can escape we can replace all air inside the volume with water.
|
||||
--]]
|
||||
|
||||
bergsee = {}
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
|
||||
--
|
||||
-- Find position
|
||||
--
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
if maxp.y <= 1024 and minp.y >= -32 then
|
||||
local perlin1 = minetest.get_perlin(318, 3, 0.6, 100)
|
||||
-- Lua Voxel Machine
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local vm_minp, vm_maxp = vm:read_from_map({x=minp.x, y=minp.y, z=minp.z-16}, {x=maxp.x+16, y=maxp.y+16, z=maxp.z+16})
|
||||
local a = VoxelArea:new{MinEdge=vm_minp, MaxEdge=vm_maxp}
|
||||
local data = vm:get_data()
|
||||
-- Assume X and Z lengths are equal
|
||||
local divlen = 32
|
||||
local divs = (maxp.x-minp.x)/divlen+1;
|
||||
for divx=0,divs-1 do
|
||||
for divz=0,divs-1 do
|
||||
local x0 = minp.x + math.floor((divx+0)*divlen)
|
||||
local z0 = minp.z + math.floor((divz+0)*divlen)
|
||||
local x1 = minp.x + math.floor((divx+1)*divlen)
|
||||
local z1 = minp.z + math.floor((divz+1)*divlen)
|
||||
-- Determine amount from perlin noise
|
||||
local amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 5 + 10)
|
||||
-- Find random positions based on this random
|
||||
local pr = PseudoRandom(seed+486)
|
||||
for i=0,amount do
|
||||
local x = pr:next(x0, x1)
|
||||
local z = pr:next(z0, z1)
|
||||
local ground_y = nil
|
||||
-- Prevent from starting underground
|
||||
local nn = minetest.get_node({x=x,y=maxp.y,z=z}).name
|
||||
if nn ~= "air" and nn ~= "ignore" then
|
||||
return
|
||||
end
|
||||
-- Find groundlevel
|
||||
for y=maxp.y,minp.y,-1 do
|
||||
local nn = minetest.get_node({x=x,y=y,z=z}).name
|
||||
if nn ~= "air" and nn~= "ignore" then
|
||||
local is_leaves = minetest.registered_nodes[nn].groups.leaves
|
||||
if is_leaves == nil or is_leaves == 0 then
|
||||
ground_y = y
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if ground_y and ground_y >= 2 then
|
||||
local p = {x=x,y=ground_y,z=z}
|
||||
local ground_name = minetest.get_node(p)
|
||||
if ground_name == "default:water_source" then return end
|
||||
local lx = pr:next(10,30)
|
||||
local lz = pr:next(10,30)
|
||||
bergsee.fill(data, a, p, lx, lz)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Write to map
|
||||
vm:set_data(data)
|
||||
vm:write_to_map(data)
|
||||
vm:update_map()
|
||||
end
|
||||
end)
|
||||
|
||||
--
|
||||
-- Make lake
|
||||
--
|
||||
|
||||
-- TODO: combine functions into one
|
||||
local function check_x(data, a, x, y, z, lx, lz)
|
||||
for xi = 0, lx do
|
||||
local vi = a:index(x+xi, y, z)
|
||||
if data[vi] == c_air or data[vi] == c_ignore then
|
||||
return true
|
||||
end
|
||||
local vii = a:index(x+xi, y, z+lz)
|
||||
if data[vii] == c_air or data[vii] == c_ignore then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function check_z(data, a, x, y, z, lx, lz)
|
||||
for zi = 0, lz do
|
||||
local vi = a:index(x, y, z+zi)
|
||||
if data[vi] == c_air or data[vi] == c_ignore then
|
||||
return true
|
||||
end
|
||||
local vii = a:index(x+lx, y, z+zi)
|
||||
if data[vii] == c_air or data[vii] == c_ignore then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function leak(data, a, j, lx, lz)
|
||||
for xi = 0, lx do
|
||||
for zi = 0, lz do
|
||||
local vi = a:index(xi, -j, zi)
|
||||
if data[vi] == c_air or data[vi] == c_ignore then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function bergsee.fill(data, a, pos, lx, lz)
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
local water_a = VoxelArea:new{MinEdge={x=0, y=-32, z=0}, MaxEdge={x=lx, y=0, z=lz}}
|
||||
local water_buffer = {}
|
||||
-- Find upper start
|
||||
local i = 0
|
||||
while i <= 16 do
|
||||
if check_x(data, a, x, y-i, z, lx, lz) or check_z(data, a, x, y-i, z, lx, lz) then
|
||||
i = i + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
if i >= 16 then return end
|
||||
-- Itterate downwards
|
||||
local j = i
|
||||
while j <= (i+16) do
|
||||
if check_x(data, a, x, y-j, z, lx, lz) or check_z(data, a, x, y-j, z, lx, lz) then
|
||||
j = j - 1
|
||||
break
|
||||
else
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
if j >= i+16 then return end
|
||||
-- print ('[bergsee] i = '.. i ..'')
|
||||
-- print ('[bergsee] j = '.. j ..'')
|
||||
-- Check bottom
|
||||
if leak(data, a, j, lx, lz) then return end
|
||||
-- Add volume to buffer
|
||||
for xi = 0, lx do
|
||||
for yi = -i, -j, -1 do
|
||||
for zi = 0, lz do
|
||||
water_buffer[water_a:index(xi, yi, zi)] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Add the water
|
||||
for xi = water_a.MinEdge.x, water_a.MaxEdge.x do
|
||||
for yi = water_a.MinEdge.y, water_a.MaxEdge.y do
|
||||
for zi = water_a.MinEdge.z, water_a.MaxEdge.z do
|
||||
if a:contains(x+xi, y+yi, z+zi) then
|
||||
local vi = a:index(x+xi, y+yi, z+zi)
|
||||
if data[vi] == c_air or data[vi] == c_ignore then
|
||||
if water_buffer[water_a:index(xi, yi, zi)] then
|
||||
data[vi] = c_water
|
||||
-- print ('[bergsee] Wasser auf (' .. x+xi .. ',' .. y+yi .. ',' .. z+zi .. ')')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -501,6 +501,9 @@ minetest.register_tool("default:axe_diamond", {
|
|||
minetest.register_tool("default:sword_wood", {
|
||||
description = "Wooden Sword",
|
||||
inventory_image = "default_tool_woodsword.png",
|
||||
on_use = function(data)
|
||||
print(data)
|
||||
end,
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1,
|
||||
max_drop_level=0,
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
-- Minetest 0.4 mod: doors
|
||||
-- See README.txt for licensing and other information.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local WALLMX = 3
|
||||
local WALLMZ = 5
|
||||
local WALLPX = 2
|
||||
local WALLPZ = 4
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
minetest.register_alias('door', 'doors:door_wood')
|
||||
minetest.register_alias('door_wood', 'doors:door_wood')
|
||||
|
||||
minetest.register_node( 'doors:door_wood', {
|
||||
description = 'Wooden Door',
|
||||
drawtype = 'signlike',
|
||||
tiles = { 'door_wood.png' },
|
||||
inventory_image = 'door_wood.png',
|
||||
wield_image = 'door_wood.png',
|
||||
paramtype2 = 'wallmounted',
|
||||
selection_box = { type = 'wallmounted' },
|
||||
groups = { choppy=2, dig_immediate=2 },
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
output = 'doors:door_wood',
|
||||
recipe = {
|
||||
{ 'default:wood', 'default:wood' },
|
||||
{ 'default:wood', 'default:wood' },
|
||||
{ 'default:wood', 'default:wood' },
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = 'fuel',
|
||||
recipe = 'doors:door_wood',
|
||||
burntime = 30,
|
||||
})
|
||||
|
||||
minetest.register_node( 'doors:door_wood_a_c', {
|
||||
Description = 'Top Closed Door',
|
||||
drawtype = 'signlike',
|
||||
tiles = { 'door_wood_a.png' },
|
||||
inventory_image = 'door_wood_a.png',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'wallmounted',
|
||||
walkable = true,
|
||||
selection_box = { type = "wallmounted", },
|
||||
groups = { choppy=2, dig_immediate=2 },
|
||||
legacy_wallmounted = true,
|
||||
drop = 'doors:door_wood',
|
||||
})
|
||||
|
||||
minetest.register_node( 'doors:door_wood_b_c', {
|
||||
Description = 'Bottom Closed Door',
|
||||
drawtype = 'signlike',
|
||||
tiles = { 'door_wood_b.png' },
|
||||
inventory_image = 'door_wood_b.png',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'wallmounted',
|
||||
walkable = true,
|
||||
selection_box = { type = "wallmounted", },
|
||||
groups = { choppy=2, dig_immediate=2 },
|
||||
legacy_wallmounted = true,
|
||||
drop = 'doors:door_wood',
|
||||
})
|
||||
|
||||
minetest.register_node( 'doors:door_wood_a_o', {
|
||||
Description = 'Top Open Door',
|
||||
drawtype = 'signlike',
|
||||
tiles = { 'door_wood_a_r.png' },
|
||||
inventory_image = 'door_wood_a_r.png',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'wallmounted',
|
||||
walkable = false,
|
||||
selection_box = { type = "wallmounted", },
|
||||
groups = { choppy=2, dig_immediate=2 },
|
||||
legacy_wallmounted = true,
|
||||
drop = 'doors:door_wood',
|
||||
})
|
||||
|
||||
minetest.register_node( 'doors:door_wood_b_o', {
|
||||
Description = 'Bottom Open Door',
|
||||
drawtype = 'signlike',
|
||||
tiles = { 'door_wood_b_r.png' },
|
||||
inventory_image = 'door_wood_b_r.png',
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'wallmounted',
|
||||
walkable = false,
|
||||
selection_box = { type = "wallmounted", },
|
||||
groups = { choppy=2, dig_immediate=2 },
|
||||
legacy_wallmounted = true,
|
||||
drop = 'doors:door_wood',
|
||||
})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local round = function( n )
|
||||
if n >= 0 then
|
||||
return math.floor( n + 0.5 )
|
||||
else
|
||||
return math.ceil( n - 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
local on_door_placed = function( pos, node, placer )
|
||||
if node.name ~= 'doors:door_wood' then return end
|
||||
|
||||
local upos = { x = pos.x, y = pos.y - 1, z = pos.z }
|
||||
local apos = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
local und = minetest.env:get_node( upos )
|
||||
local abv = minetest.env:get_node( apos )
|
||||
|
||||
local dir = placer:get_look_dir()
|
||||
|
||||
if round( dir.x ) == 1 then
|
||||
newparam = WALLMX
|
||||
elseif round( dir.x ) == -1 then
|
||||
newparam = WALLPX
|
||||
elseif round( dir.z ) == 1 then
|
||||
newparam = WALLMZ
|
||||
elseif round( dir.z ) == -1 then
|
||||
newparam = WALLPZ
|
||||
end
|
||||
|
||||
if und.name == 'air' then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_a_c', param2 = newparam } )
|
||||
minetest.env:add_node( upos, { name = 'doors:door_wood_b_c', param2 = newparam } )
|
||||
elseif abv.name == 'air' then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_b_c', param2 = newparam } )
|
||||
minetest.env:add_node( apos, { name = 'doors:door_wood_a_c', param2 = newparam } )
|
||||
else
|
||||
minetest.env:remove_node( pos )
|
||||
placer:get_inventory():add_item( "main", 'doors:door_wood' )
|
||||
minetest.chat_send_player( placer:get_player_name(), 'not enough space' )
|
||||
end
|
||||
end
|
||||
|
||||
local on_door_punched = function( pos, node, puncher )
|
||||
if string.find( node.name, 'doors:door_wood' ) == nil then return end
|
||||
|
||||
local upos = { x = pos.x, y = pos.y - 1, z = pos.z }
|
||||
local apos = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
|
||||
if string.find( node.name, '_c', -2 ) ~= nil then
|
||||
if node.param2 == WALLPX then
|
||||
newparam = WALLMZ
|
||||
elseif node.param2 == WALLMZ then
|
||||
newparam = WALLMX
|
||||
elseif node.param2 == WALLMX then
|
||||
newparam = WALLPZ
|
||||
elseif node.param2 == WALLPZ then
|
||||
newparam = WALLPX
|
||||
end
|
||||
elseif string.find( node.name, '_o', -2 ) ~= nil then
|
||||
if node.param2 == WALLMZ then
|
||||
newparam = WALLPX
|
||||
elseif node.param2 == WALLMX then
|
||||
newparam = WALLMZ
|
||||
elseif node.param2 == WALLPZ then
|
||||
newparam = WALLMX
|
||||
elseif node.param2 == WALLPX then
|
||||
newparam = WALLPZ
|
||||
end
|
||||
end
|
||||
|
||||
if ( node.name == 'doors:door_wood_a_c' ) then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_a_o', param2 = newparam } )
|
||||
minetest.env:add_node( upos, { name = 'doors:door_wood_b_o', param2 = newparam } )
|
||||
|
||||
elseif ( node.name == 'doors:door_wood_b_c' ) then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_b_o', param2 = newparam } )
|
||||
minetest.env:add_node( apos, { name = 'doors:door_wood_a_o', param2 = newparam } )
|
||||
|
||||
elseif ( node.name == 'doors:door_wood_a_o' ) then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_a_c', param2 = newparam } )
|
||||
minetest.env:add_node( upos, { name = 'doors:door_wood_b_c', param2 = newparam } )
|
||||
|
||||
elseif ( node.name == 'doors:door_wood_b_o' ) then
|
||||
minetest.env:add_node( pos, { name = 'doors:door_wood_b_c', param2 = newparam } )
|
||||
minetest.env:add_node( apos, { name = 'doors:door_wood_a_c', param2 = newparam } )
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local on_door_digged = function( pos, node, digger )
|
||||
local upos = { x = pos.x, y = pos.y - 1, z = pos.z }
|
||||
local apos = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
|
||||
if ( node.name == 'doors:door_wood_a_c' ) or ( node.name == 'doors:door_wood_a_o' ) then
|
||||
minetest.env:remove_node( upos )
|
||||
elseif ( node.name == 'doors:door_wood_b_c' ) or ( node.name == 'doors:door_wood_b_o' ) then
|
||||
minetest.env:remove_node( apos )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
minetest.register_on_placenode( on_door_placed )
|
||||
minetest.register_on_punchnode( on_door_punched )
|
||||
minetest.register_on_dignode( on_door_digged )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
minetest-protect
|
||||
================
|
||||
|
||||
Protector mod for minetest
|
||||
based on glomie's mod, remade by Zeg9 and reworked by TenPlus1 to support minetest 0.4.9
|
|
@ -1 +1 @@
|
|||
default
|
||||
default
|
|
@ -1,36 +1,19 @@
|
|||
-- Zeg9's protector mod
|
||||
-- based on glomie's mod of the same name
|
||||
-- Released under WTFPL
|
||||
|
||||
|
||||
-- FIXME: use a mesh instead of the buggy wielditem, for protector:display
|
||||
-- but that isn't possible yet since models won't take care of the texture's alpha channel...
|
||||
|
||||
|
||||
minetest.register_privilege("delprotect","Delete other's protection by sneaking")
|
||||
minetest.register_privilege("delprotect","Delete other's protection")
|
||||
|
||||
protector = {}
|
||||
|
||||
protector.node = "protector:protect"
|
||||
protector.item = "protector:stick"
|
||||
|
||||
protector.get_member_list = function(meta)
|
||||
s = meta:get_string("members")
|
||||
list = s:split(" ")
|
||||
local s = meta:get_string("members")
|
||||
local list = s:split(" ")
|
||||
return list
|
||||
end
|
||||
|
||||
protector.set_member_list = function(meta, list)
|
||||
s = ""
|
||||
for _, i in ipairs(list) do
|
||||
s = s .. i .. " "
|
||||
end
|
||||
s = s:sub(0,s:len()-1) -- remove last space
|
||||
meta:set_string("members",s)
|
||||
meta:set_string("members", table.concat(list, " "))
|
||||
end
|
||||
|
||||
protector.is_member = function (meta, name)
|
||||
list = protector.get_member_list(meta)
|
||||
local list = protector.get_member_list(meta)
|
||||
for _, n in ipairs(list) do
|
||||
if n == name then
|
||||
return true
|
||||
|
@ -41,13 +24,13 @@ end
|
|||
|
||||
protector.add_member = function(meta, name)
|
||||
if protector.is_member(meta, name) then return end
|
||||
list = protector.get_member_list(meta)
|
||||
local list = protector.get_member_list(meta)
|
||||
table.insert(list,name)
|
||||
protector.set_member_list(meta,list)
|
||||
end
|
||||
|
||||
protector.del_member = function(meta,name)
|
||||
list = protector.get_member_list(meta)
|
||||
local list = protector.get_member_list(meta)
|
||||
for i, n in ipairs(list) do
|
||||
if n == name then
|
||||
table.remove(list, i)
|
||||
|
@ -57,235 +40,243 @@ protector.del_member = function(meta,name)
|
|||
protector.set_member_list(meta,list)
|
||||
end
|
||||
|
||||
protector.generate_formspec = function (meta)
|
||||
-- Protector Interface
|
||||
|
||||
protector.generate_formspec = function(meta)
|
||||
if meta:get_int("page") == nil then meta:set_int("page",0) end
|
||||
formspec = "size[8,8]"
|
||||
local formspec = "size[8,7]"
|
||||
.."label[0,0;-- Protector interface --]"
|
||||
.."label[0,1;Punch the node to show the protected area.]"
|
||||
.."label[0,2;Current members:]"
|
||||
.."label[0,1;Punch node to show protected area]"
|
||||
.."label[0,2;Members: (type nick, press Enter to add)]"
|
||||
members = protector.get_member_list(meta)
|
||||
|
||||
local npp = 15 -- names per page, for the moment is 4*4 (-1 for the + button)
|
||||
local npp = 12 -- was 15, names per page, for the moment is 4*4 (-1 for the + button)
|
||||
local s = 0
|
||||
local i = 0
|
||||
for _, member in ipairs(members) do
|
||||
if s < meta:get_int("page")*15 then s = s +1 else
|
||||
if i < 15 then
|
||||
formspec = formspec .. "button["..(i%4*2)..","..math.floor(i/4+3)..";1.5,.5;protector_member;"..member.."]"
|
||||
formspec = formspec .. "button["..(i%4*2+1.25)..","..math.floor(i/4+3)..";.75,.5;protector_del_member_"..member..";X]"
|
||||
if i < npp then
|
||||
formspec = formspec .. "button["..(i%4*2)..","
|
||||
..math.floor(i/4+3)..";1.5,.5;protector_member;"..member.."]"
|
||||
formspec = formspec .. "button["..(i%4*2+1.25)..","
|
||||
..math.floor(i/4+3)..";.75,.5;protector_del_member_"..member..";X]"
|
||||
end
|
||||
i = i +1
|
||||
end
|
||||
end
|
||||
local add_i = i
|
||||
if add_i > npp then add_i = npp end
|
||||
formspec = formspec
|
||||
if add_i < npp then
|
||||
formspec = formspec
|
||||
.."field["..(add_i%4*2+1/3)..","..(math.floor(add_i/4+3)+1/3)..";1.433,.5;protector_add_member;;]"
|
||||
.."button["..(add_i%4*2+1.25)..","..math.floor(add_i/4+3)..";.75,.5;protector_submit;+]"
|
||||
|
||||
if s > 0 then
|
||||
formspec = formspec .. "button[0,7;1,1;protector_page_prev;<<]"
|
||||
end
|
||||
if i > npp then
|
||||
formspec = formspec .. "button[1,7;1,1;protector_page_next;>>]"
|
||||
end
|
||||
formspec = formspec .. "label[2,7;Page "..(meta:get_int("page")+1).."/"..math.floor((s+i-1)/15+1).."]"
|
||||
formspec = formspec.."button_exit[1,6.2;2,0.5;close_me;<< Back]"
|
||||
return formspec
|
||||
end
|
||||
|
||||
-- ACTUAL PROTECTION SECTION
|
||||
|
||||
-- r: radius to check for protects
|
||||
-- Infolevel:
|
||||
-- * 0 for no info
|
||||
-- * 1 for "This area is owned by <owner> !" if you can't dig
|
||||
-- * 2 for "This area is owned by <owner>.
|
||||
-- Members are: <members>.", even if you can dig
|
||||
|
||||
protector.can_dig = function(r,pos,digger,onlyowner,infolevel)
|
||||
if infolevel == nil then infolevel = 1 end
|
||||
if not digger or not digger.get_player_name then return false end
|
||||
-- Delprotect privileged users can override protections by holding sneak
|
||||
if minetest.get_player_privs(digger:get_player_name()).delprotect and
|
||||
digger:get_player_control().sneak then
|
||||
return true end
|
||||
|
||||
if not digger then
|
||||
return false
|
||||
end
|
||||
|
||||
local whois = digger
|
||||
|
||||
-- Delprotect privileged users can override protections
|
||||
|
||||
if minetest.check_player_privs(whois, {delprotect=true}) and infolevel < 3 then
|
||||
return true
|
||||
end
|
||||
|
||||
if infolevel == 3 then infolevel = 1 end
|
||||
|
||||
-- Find the protector nodes
|
||||
|
||||
local positions = minetest.find_nodes_in_area(
|
||||
{x=pos.x-r, y=pos.y-r, z=pos.z-r},
|
||||
{x=pos.x+r, y=pos.y+r, z=pos.z+r},
|
||||
protector.node)
|
||||
"protector:protect")
|
||||
|
||||
for _, pos in ipairs(positions) do
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
if owner ~= digger:get_player_name() then
|
||||
if onlyowner or not protector.is_member(meta, digger:get_player_name()) then
|
||||
|
||||
if owner ~= whois then
|
||||
if onlyowner or not protector.is_member(meta, whois) then
|
||||
if infolevel == 1 then
|
||||
minetest.chat_send_player(digger:get_player_name(), "This area is owned by "..owner.." !")
|
||||
local hp = digger:get_hp()-12
|
||||
digger:set_hp(hp)
|
||||
minetest.chat_send_player(whois, "This area is owned by "..owner.." !")
|
||||
elseif infolevel == 2 then
|
||||
minetest.chat_send_player(digger:get_player_name(),"This area is owned by "..meta:get_string("owner")..".")
|
||||
minetest.chat_send_player(whois,"This area is owned by "..meta:get_string("owner")..".")
|
||||
if meta:get_string("members") ~= "" then
|
||||
minetest.chat_send_player(digger:get_player_name(),"Members are: "..meta:get_string("members")..".")
|
||||
minetest.chat_send_player(whois,"Members: "..meta:get_string("members")..".")
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if infolevel == 2 then
|
||||
if #positions < 1 then
|
||||
minetest.chat_send_player(digger:get_player_name(),"This area is not protected.")
|
||||
minetest.chat_send_player(whois,"This area is not protected.")
|
||||
else
|
||||
local meta = minetest.env:get_meta(positions[1])
|
||||
minetest.chat_send_player(digger:get_player_name(),"This area is owned by "..meta:get_string("owner")..".")
|
||||
minetest.chat_send_player(whois,"This area is owned by "..meta:get_string("owner")..".")
|
||||
if meta:get_string("members") ~= "" then
|
||||
minetest.chat_send_player(digger:get_player_name(),"Members are: "..meta:get_string("members")..".")
|
||||
minetest.chat_send_player(whois,"Members: "..meta:get_string("members")..".")
|
||||
end
|
||||
end
|
||||
minetest.chat_send_player(digger:get_player_name(),"You can build here.")
|
||||
minetest.chat_send_player(whois,"You can build here.")
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local old_node_dig = minetest.node_dig
|
||||
function minetest.node_dig(pos, node, digger)
|
||||
local ok=true
|
||||
if node.name ~= protector.node then
|
||||
ok = protector.can_dig(5,pos,digger)
|
||||
else ok = protector.can_dig(5,pos,digger,true)
|
||||
end
|
||||
if ok == true then
|
||||
old_node_dig(pos, node, digger)
|
||||
-- Can node be added or removed, if so return node else true (for protected)
|
||||
|
||||
protector.old_is_protected = minetest.is_protected
|
||||
minetest.is_protected = function(pos, digger)
|
||||
|
||||
if protector.can_dig(5, pos, digger, false, 1) then
|
||||
return protector.old_is_protected(pos, digger)
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local old_node_place = minetest.item_place
|
||||
-- Make sure protection block doesn't overlap another block's area
|
||||
|
||||
protector.old_node_place = minetest.item_place
|
||||
function minetest.item_place(itemstack, placer, pointed_thing)
|
||||
if itemstack:get_definition().type == "node" then
|
||||
local ok=true
|
||||
if itemstack:get_name() ~= protector.node then
|
||||
local pos = pointed_thing.above
|
||||
ok = protector.can_dig(5,pos,placer)
|
||||
|
||||
if itemstack:get_name() == "protector:protect" then
|
||||
local pos = pointed_thing.above
|
||||
local user = placer:get_player_name()
|
||||
if protector.can_dig(10, pos, user, true, 3) then
|
||||
--
|
||||
else
|
||||
local pos = pointed_thing.above
|
||||
ok = protector.can_dig(10,pos,placer,true)
|
||||
end
|
||||
if ok == true then
|
||||
return old_node_place(itemstack, placer, pointed_thing)
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
return old_node_place(itemstack, placer, pointed_thing)
|
||||
minetest.chat_send_player(placer:get_player_name(),"Overlaps into another protected area")
|
||||
return protector.old_node_place(itemstack, placer, pos)
|
||||
end
|
||||
end
|
||||
|
||||
return protector.old_node_place(itemstack, placer, pointed_thing)
|
||||
end
|
||||
protect = {}
|
||||
minetest.register_node(protector.node, {
|
||||
|
||||
-- END
|
||||
|
||||
minetest.register_node("protector:protect", {
|
||||
description = "Protection",
|
||||
tile_images = {"protector_top.png","protector_top.png","protector_side.png"},
|
||||
tiles = {"protector_top.png","protector_top.png","protector_side.png"},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
groups = {dig_immediate=2},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type="fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
selection_box = { type="regular" },
|
||||
paramtype = "light",
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name() or "")
|
||||
meta:set_string("infotext", "Protection (owned by "..
|
||||
meta:get_string("owner")..")")
|
||||
meta:get_string("owner")..")")
|
||||
meta:set_string("members", "")
|
||||
--meta:set_string("formspec",protector.generate_formspec(meta))
|
||||
end,
|
||||
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
protector.can_dig(5,pointed_thing.under,user:get_player_name(),false,2)
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
if protector.can_dig(1,pos,clicker,true) then
|
||||
minetest.show_formspec(
|
||||
clicker:get_player_name(),
|
||||
"protector_"..minetest.pos_to_string(pos),
|
||||
protector.generate_formspec(meta)
|
||||
if protector.can_dig(1,pos,clicker:get_player_name(),true,1) then
|
||||
minetest.show_formspec(clicker:get_player_name(),
|
||||
"protector_"..minetest.pos_to_string(pos), protector.generate_formspec(meta)
|
||||
)
|
||||
end
|
||||
end,
|
||||
|
||||
on_punch = function(pos, node, puncher)
|
||||
if not protector.can_dig(1,pos,puncher,true) then
|
||||
if not protector.can_dig(1,pos,puncher:get_player_name(),true,1) then
|
||||
return
|
||||
end
|
||||
local objs = minetest.env:get_objects_inside_radius(pos,.5) -- a radius of .5 since the entity serialization seems to be not that precise
|
||||
local removed = false
|
||||
|
||||
local objs = minetest.env:get_objects_inside_radius(pos,.5)
|
||||
minetest.env:add_entity(pos, "protector:display")
|
||||
minetest.env:get_node_timer(pos):start(10)
|
||||
end,
|
||||
|
||||
on_timer = function(pos)
|
||||
local objs = minetest.env:get_objects_inside_radius(pos,.5)
|
||||
for _, o in pairs(objs) do
|
||||
if (not o:is_player()) and o:get_luaentity().name == "protector:display" then
|
||||
o:remove()
|
||||
removed = true
|
||||
end
|
||||
end
|
||||
if not removed then -- nothing was removed: there wasn't the entity
|
||||
minetest.env:add_entity(pos, "protector:display")
|
||||
end
|
||||
end,
|
||||
})
|
||||
-- remove formspecs from older versions of the mod
|
||||
minetest.register_abm({
|
||||
nodenames = {protector.node},
|
||||
interval = 5.0,
|
||||
chance = 1,
|
||||
action = function(pos,...)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec","")
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player,formname,fields)
|
||||
if string.sub(formname,0,string.len("protector_")) == "protector_" then
|
||||
local pos_s = string.sub(formname,string.len("protector_")+1)
|
||||
local pos = minetest.string_to_pos(pos_s)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
|
||||
if meta:get_int("page") == nil then meta:set_int("page",0) end
|
||||
if not protector.can_dig(1,pos,player,true) then
|
||||
|
||||
if not protector.can_dig(1,pos,player:get_player_name(),true,1) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.protector_add_member then
|
||||
for _, i in ipairs(fields.protector_add_member:split(" ")) do
|
||||
protector.add_member(meta,i)
|
||||
end
|
||||
end
|
||||
|
||||
for field, value in pairs(fields) do
|
||||
if string.sub(field,0,string.len("protector_del_member_"))=="protector_del_member_" then
|
||||
protector.del_member(meta, string.sub(field,string.len("protector_del_member_")+1))
|
||||
end
|
||||
end
|
||||
|
||||
if fields.protector_page_prev then
|
||||
meta:set_int("page",meta:get_int("page")-1)
|
||||
end
|
||||
|
||||
if fields.protector_page_next then
|
||||
meta:set_int("page",meta:get_int("page")+1)
|
||||
end
|
||||
minetest.show_formspec(
|
||||
player:get_player_name(), formname,
|
||||
protector.generate_formspec(meta)
|
||||
)
|
||||
|
||||
if fields.close_me then
|
||||
meta:set_int("page",meta:get_int("page"))
|
||||
else minetest.show_formspec(player:get_player_name(), formname, protector.generate_formspec(meta))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_craftitem(protector.item, {
|
||||
description = "Protection tool",
|
||||
inventory_image = "protector_stick.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
protector.can_dig(5,pointed_thing.under,user,false,2)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = '"' .. protector.node .. '" 4',
|
||||
output = "protector:protect 4",
|
||||
recipe = {
|
||||
{"default:stone","default:stone","default:stone"},
|
||||
{"default:stone","default:steel_ingot","default:stone"},
|
||||
{"default:stone","default:stone","default:stone"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = protector.item,
|
||||
recipe = {
|
||||
{protector.node},
|
||||
{'default:stick'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_entity("protector:display", {
|
||||
physical = false,
|
||||
|
@ -294,7 +285,7 @@ minetest.register_entity("protector:display", {
|
|||
visual_size = {x=1.0/1.5,y=1.0/1.5}, -- wielditem seems to be scaled to 1.5 times original node size
|
||||
textures = {"protector:display_node"},
|
||||
on_step = function(self, dtime)
|
||||
if minetest.get_node(self.object:getpos()).name ~= protector.node then
|
||||
if minetest.get_node(self.object:getpos()).name ~= "protector:protect" then
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
@ -304,6 +295,7 @@ minetest.register_entity("protector:display", {
|
|||
-- Display-zone node.
|
||||
-- Do NOT place the display as a node
|
||||
-- it is made to be used as an entity (see above)
|
||||
|
||||
minetest.register_node("protector:display_node", {
|
||||
tiles = {"protector_display.png"},
|
||||
use_texture_alpha = true,
|
||||
|
@ -331,6 +323,4 @@ minetest.register_node("protector:display_node", {
|
|||
paramtype = "light",
|
||||
groups = {dig_immediate=3,not_in_creative_inventory=1},
|
||||
drop = "",
|
||||
})
|
||||
|
||||
|
||||
})
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 556 B |
Before Width: | Height: | Size: 631 B After Width: | Height: | Size: 487 B |
|
@ -39,7 +39,6 @@ abstract_trees.grow_conifertree = function(pos)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
-- abm
|
||||
minetest.register_abm({
|
||||
nodenames = "trees:sapling_conifer",
|
||||
|
|