Add files via upload
parent
8faad112b2
commit
85cdc084be
|
@ -0,0 +1,48 @@
|
|||
minetest.register_on_receiving_chat_message(function(message)
|
||||
if message:sub(1, 1) == "#" and minetest.settings:get_bool("ignore_status_messages") ~= false then
|
||||
return true
|
||||
elseif message:find('\1b@mcl_death_messages\1b') and minetest.settings:get_bool("mark_deathmessages") ~= false then
|
||||
minetest.display_chat_message(minetest.colorize("#F25819", "[Deathmessage] ") .. message)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
function minetest.send_colorized(message)
|
||||
local starts_with = message:sub(1, 1)
|
||||
|
||||
if starts_with == "/" or starts_with == "." then return end
|
||||
|
||||
local reverse = minetest.settings:get_bool("chat_reverse")
|
||||
|
||||
if reverse then
|
||||
local msg = ""
|
||||
for i = 1, #message do
|
||||
msg = message:sub(i, i) .. msg
|
||||
end
|
||||
message = msg
|
||||
end
|
||||
|
||||
local use_chat_color = minetest.settings:get_bool("use_chat_color")
|
||||
local color = minetest.settings:get("chat_color")
|
||||
|
||||
if use_chat_color and color then
|
||||
local msg
|
||||
if color == "rainbow" then
|
||||
msg = minetest.rainbow(message)
|
||||
else
|
||||
msg = minetest.colorize(color, message)
|
||||
end
|
||||
message = msg
|
||||
end
|
||||
|
||||
minetest.send_chat_message(message)
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_on_sending_chat_message(minetest.send_colorized)
|
||||
|
||||
|
||||
minetest.register_cheat("IgnoreStatus", "Chat", "ignore_status_messages")
|
||||
minetest.register_cheat("DeathMessages", "Chat", "mark_deathmessages")
|
||||
minetest.register_cheat("ColoredChat", "Chat", "use_chat_color")
|
||||
minetest.register_cheat("ReversedChat", "Chat", "chat_reverse")
|
|
@ -0,0 +1,3 @@
|
|||
name = chat
|
||||
author = Fleckenstein
|
||||
description = The chat modifications of Dragonfireclient
|
|
@ -0,0 +1,3 @@
|
|||
chat_color (Chat Color) string white
|
||||
chat_reverse (Reverse Chat messages) bool false
|
||||
ignore_status_messages (Ignore status messages from server) bool false
|
|
@ -0,0 +1,179 @@
|
|||
local drop_action = InventoryAction("drop")
|
||||
|
||||
local strip_move_act = InventoryAction("move")
|
||||
strip_move_act:to("current_player", "craft", 1)
|
||||
local strip_craft_act = InventoryAction("craft")
|
||||
strip_craft_act:craft("current_player")
|
||||
local strip_move_back_act = InventoryAction("move")
|
||||
strip_move_back_act:from("current_player", "craftresult", 1)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local player = minetest.localplayer
|
||||
if not player then return end
|
||||
local item = player:get_wielded_item()
|
||||
local itemdef = minetest.get_item_def(item:get_name())
|
||||
local wieldindex = player:get_wield_index()
|
||||
-- AutoRefill
|
||||
if minetest.settings:get_bool("autorefill") and itemdef then
|
||||
local space = item:get_free_space()
|
||||
local i = minetest.find_item(item:get_name(), wieldindex + 1)
|
||||
if i and space > 0 then
|
||||
local move_act = InventoryAction("move")
|
||||
move_act:to("current_player", "main", wieldindex)
|
||||
move_act:from("current_player", "main", i)
|
||||
move_act:set_count(space)
|
||||
move_act:apply()
|
||||
end
|
||||
end
|
||||
-- AutoPlanks (Strip in DF)
|
||||
if minetest.settings:get_bool("autoplanks") then
|
||||
if itemdef and itemdef.groups.tree and player:get_control().place then
|
||||
strip_move_act:from("current_player", "main", wieldindex)
|
||||
strip_move_back_act:to("current_player", "main", wieldindex)
|
||||
strip_move_act:apply()
|
||||
strip_craft_act:apply()
|
||||
strip_move_back_act:apply()
|
||||
end
|
||||
end
|
||||
-- AutoEject
|
||||
if minetest.settings:get_bool("autoeject") then
|
||||
local list = (minetest.settings:get("eject_items") or ""):split(",")
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
for index, stack in pairs(inventory.main) do
|
||||
if table.indexof(list, stack:get_name()) ~= -1 then
|
||||
drop_action:from("current_player", "main", index)
|
||||
drop_action:apply()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_list_command("eject", "Configure AutoEject", "eject_items")
|
||||
|
||||
-- AutoTool
|
||||
|
||||
local function check_tool(stack, node_groups, old_best_time)
|
||||
local toolcaps = stack:get_tool_capabilities()
|
||||
if not toolcaps then return end
|
||||
local best_time = old_best_time
|
||||
for group, groupdef in pairs(toolcaps.groupcaps) do
|
||||
local level = node_groups[group]
|
||||
if level then
|
||||
local this_time = groupdef.times[level]
|
||||
if this_time and this_time < best_time then
|
||||
best_time = this_time
|
||||
end
|
||||
end
|
||||
end
|
||||
return best_time < old_best_time, best_time
|
||||
end
|
||||
|
||||
local function find_best_tool(nodename, switch)
|
||||
local player = minetest.localplayer
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
local node_groups = minetest.get_node_def(nodename).groups
|
||||
local new_index = player:get_wield_index()
|
||||
local is_better, best_time = false, math.huge
|
||||
|
||||
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
|
||||
if inventory.hand then
|
||||
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
|
||||
end
|
||||
|
||||
for index, stack in ipairs(inventory.main) do
|
||||
is_better, best_time = check_tool(stack, node_groups, best_time)
|
||||
if is_better then
|
||||
new_index = index
|
||||
end
|
||||
end
|
||||
|
||||
return new_index
|
||||
end
|
||||
|
||||
function minetest.select_best_tool(nodename)
|
||||
minetest.localplayer:set_wield_index(find_best_tool(nodename))
|
||||
end
|
||||
|
||||
local new_index, old_index, pointed_pos
|
||||
|
||||
minetest.register_on_punchnode(function(pos, node)
|
||||
if minetest.settings:get_bool("autotool") then
|
||||
pointed_pos = pos
|
||||
old_index = old_index or minetest.localplayer:get_wield_index()
|
||||
new_index = find_best_tool(node.name)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
local player = minetest.localplayer
|
||||
if not new_index then return end
|
||||
if minetest.settings:get_bool("autotool") then
|
||||
local pt = minetest.get_pointed_thing()
|
||||
if pt and pt.type == "node" and vector.equals(minetest.get_pointed_thing_position(pt), pointed_pos) and player:get_control().dig then
|
||||
player:set_wield_index(new_index)
|
||||
return
|
||||
end
|
||||
end
|
||||
player:set_wield_index(old_index)
|
||||
new_index, old_index, pointed_pos = nil
|
||||
end)
|
||||
|
||||
-- Enderchest
|
||||
|
||||
function get_itemslot_bg(x, y, w, h)
|
||||
local out = ""
|
||||
for i = 0, w - 1, 1 do
|
||||
for j = 0, h - 1, 1 do
|
||||
out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]"
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local enderchest_formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Ender Chest")).."]"..
|
||||
"list[current_player;enderchest;0,0.5;9,3;]"..
|
||||
get_itemslot_bg(0,0.5,9,3)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;enderchest]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
function minetest.open_enderchest()
|
||||
minetest.show_formspec("inventory:enderchest", enderchest_formspec)
|
||||
end
|
||||
|
||||
-- HandSlot
|
||||
|
||||
local hand_formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Hand")).."]"..
|
||||
"list[current_player;hand;0,0.5;1,1;]"..
|
||||
get_itemslot_bg(0,0.5,1,1)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;hand]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
function minetest.open_handslot()
|
||||
minetest.show_formspec("inventory:hand", hand_formspec)
|
||||
end
|
||||
|
||||
minetest.register_cheat("AutoEject", "Inventory", "autoeject")
|
||||
minetest.register_cheat("AutoTool", "Inventory", "autotool")
|
||||
minetest.register_cheat("Hand", "Inventory", minetest.open_handslot)
|
||||
minetest.register_cheat("Enderchest", "Inventory", minetest.open_enderchest)
|
||||
minetest.register_cheat("AutoPlanks", "Inventory", "autoplanks")
|
||||
minetest.register_cheat("AutoRefill", "Inventory", "autorefill")
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
dofile(modpath .. "/next_item.lua")
|
||||
dofile(modpath .. "/invhack.lua")
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
minetest.register_chatcommand("invhack", {
|
||||
func = function(player)
|
||||
minetest.show_formspec(
|
||||
"invhack:invhack",
|
||||
""
|
||||
.. "size[8,7.5]"
|
||||
.. "list[player:" .. player .. ";main;0,3.5;8,4;]"
|
||||
.. "list[player:" .. player .. ";craft;3,0;3,3;]"
|
||||
.. "list[player:" .. player .. ";craftpreview;7,1;1,1;]"
|
||||
)
|
||||
end
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
name = inventory
|
||||
author = Fleckenstein
|
||||
description = The inventory cheats for Dragonfireclient
|
||||
dependencies = list
|
|
@ -0,0 +1,18 @@
|
|||
local elapsed_time = 0
|
||||
local tick_time = 0.05
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
elapsed_time = elapsed_time + dtime
|
||||
if elapsed_time < tick_time then return end
|
||||
local player = minetest.localplayer
|
||||
if not player then return end
|
||||
local item = player:get_wielded_item()
|
||||
if item:get_count() == 0 and minetest.settings:get_bool("next_item") then
|
||||
local index = player:get_wield_index()
|
||||
player:set_wield_index(index + 1)
|
||||
end
|
||||
elapsed_time = 0
|
||||
end)
|
||||
|
||||
minetest.register_cheat("NextItem", "Inventory", "next_item")
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
next_item (NextItem) bool false
|
||||
autotool (AutoTool) bool false
|
||||
autoeject (AutoEject) bool false
|
||||
eject_items (AutoEject Items) string
|
|
@ -0,0 +1,47 @@
|
|||
list = {}
|
||||
|
||||
function list.new(desc, setting)
|
||||
local def = {}
|
||||
def.description = desc
|
||||
def.params = "del <item> | add <item> | list"
|
||||
function def.func(param)
|
||||
local list = (minetest.settings:get(setting) or ""):split(",")
|
||||
if param == "list" then
|
||||
return true, table.concat(list, ", ")
|
||||
else
|
||||
local sparam = param:split(" ")
|
||||
local cmd = sparam[1]
|
||||
local item = sparam[2]
|
||||
if cmd == "del" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i == -1 then
|
||||
return false, item .. " is not on the list."
|
||||
else
|
||||
table.remove(list, i)
|
||||
minetest.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Removed " .. item .. " from the list."
|
||||
end
|
||||
elseif cmd == "add" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i ~= -1 then
|
||||
return false, item .. " is already on the list."
|
||||
else
|
||||
table.insert(list, item)
|
||||
minetest.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Added " .. item .. " to the list."
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "Invalid usage. (See /help <command>)"
|
||||
end
|
||||
return def
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("xray", list.new("Configure X-Ray", "xray_nodes"))
|
||||
--minetest.register_chatcommand("Configure Search Nodes", "search_nodes")
|
|
@ -0,0 +1,44 @@
|
|||
local function register_keypress_cheat(cheat, keyname, condition)
|
||||
local was_active = false
|
||||
minetest.register_globalstep(function()
|
||||
local is_active = minetest.settings:get_bool(cheat) and (not condition or condition())
|
||||
if is_active then
|
||||
minetest.set_keypress(keyname, true)
|
||||
elseif was_active then
|
||||
minetest.set_keypress(keyname, false)
|
||||
end
|
||||
was_active = is_active
|
||||
end)
|
||||
end
|
||||
|
||||
register_keypress_cheat("autosneak", "sneak", function()
|
||||
return minetest.localplayer:is_touching_ground()
|
||||
end)
|
||||
register_keypress_cheat("autosprint", "special1")
|
||||
|
||||
local legit_override
|
||||
|
||||
local function get_override_factor(name)
|
||||
if minetest.settings:get_bool("override_" .. name) then
|
||||
return tonumber(minetest.settings:get("override_" .. name .. "_factor")) or 1
|
||||
else
|
||||
return 1.0
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if not legit_override then return end
|
||||
local override = table.copy(legit_override)
|
||||
override.speed = override.speed * get_override_factor("speed")
|
||||
override.jump = override.jump * get_override_factor("jump")
|
||||
override.gravity = override.gravity * get_override_factor("gravity")
|
||||
minetest.localplayer:set_physics_override(override)
|
||||
end)
|
||||
|
||||
minetest.register_on_recieve_physics_override(function(override)
|
||||
legit_override = override
|
||||
return true
|
||||
end)
|
||||
|
||||
minetest.register_cheat("AutoSneak", "Movement", "autosneak")
|
||||
minetest.register_cheat("AutoSprint", "Movement", "autosprint")
|
|
@ -0,0 +1,3 @@
|
|||
name = autosneak
|
||||
desciption = Adds the AutoSneak feature to dragonfire.
|
||||
author = Fleckenstein
|
|
@ -0,0 +1 @@
|
|||
autosneak (AutoSneak) bool false
|
|
@ -0,0 +1,33 @@
|
|||
perlin = dofile(minetest.get_modpath("perlin") .. "/perlin.lua")
|
||||
|
||||
local start, height, stretch
|
||||
|
||||
minetest.register_chatcommand("perlin", {
|
||||
description = "Start perlin terraforming",
|
||||
param = "<height> <stretch>",
|
||||
func = function(param)
|
||||
local sparam = param:split(" ")
|
||||
start, height, stretch = math.floor(minetest.localplayer:get_pos().y), sparam[1], sparam[2]
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("perlinstop", {
|
||||
description = "Abort perlin terraforming",
|
||||
func = function(param)
|
||||
start, height, stretch = nil
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if start then
|
||||
local player = minetest.localplayer
|
||||
local pos = vector.floor(player:get_pos())
|
||||
for x = pos.x - 1, pos.x + 1 do
|
||||
for z = pos.z - 1, pos.z + 1 do
|
||||
local y = math.floor(start + height * perlin:noise(x / stretch, z / stretch))
|
||||
local p = vector.new(x, y, z)
|
||||
minetest.place_node(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,3 @@
|
|||
name = perlin
|
||||
description = A bot that does terraforming automatically using perlin noise.
|
||||
author = Fleckenstein
|
|
@ -0,0 +1,144 @@
|
|||
--[[
|
||||
Implemented as described here:
|
||||
http://flafla2.github.io/2014/08/09/perlinnoise.html
|
||||
]]--
|
||||
|
||||
local perlin = {}
|
||||
perlin.p = {}
|
||||
|
||||
local bit32 = {}
|
||||
function bit32.band(a, b)
|
||||
local result = 0
|
||||
local bitval = 1
|
||||
while a > 0 and b > 0 do
|
||||
if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
|
||||
result = result + bitval -- set the current bit
|
||||
end
|
||||
bitval = bitval * 2 -- shift left
|
||||
a = math.floor(a/2) -- shift right
|
||||
b = math.floor(b/2)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Hash lookup table as defined by Ken Perlin
|
||||
-- This is a randomly arranged array of all numbers from 0-255 inclusive
|
||||
local permutation = {151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||
}
|
||||
|
||||
-- p is used to hash unit cube coordinates to [0, 255]
|
||||
for i=0,255 do
|
||||
-- Convert to 0 based index table
|
||||
perlin.p[i] = permutation[i+1]
|
||||
-- Repeat the array to avoid buffer overflow in hash function
|
||||
perlin.p[i+256] = permutation[i+1]
|
||||
end
|
||||
|
||||
-- Return range: [-1, 1]
|
||||
function perlin:noise(x, y, z)
|
||||
y = y or 0
|
||||
z = z or 0
|
||||
|
||||
-- Calculate the "unit cube" that the point asked will be located in
|
||||
local xi = bit32.band(math.floor(x),255)
|
||||
local yi = bit32.band(math.floor(y),255)
|
||||
local zi = bit32.band(math.floor(z),255)
|
||||
|
||||
-- Next we calculate the location (from 0 to 1) in that cube
|
||||
x = x - math.floor(x)
|
||||
y = y - math.floor(y)
|
||||
z = z - math.floor(z)
|
||||
|
||||
-- We also fade the location to smooth the result
|
||||
local u = self.fade(x)
|
||||
local v = self.fade(y)
|
||||
local w = self.fade(z)
|
||||
|
||||
-- Hash all 8 unit cube coordinates surrounding input coordinate
|
||||
local p = self.p
|
||||
local A, AA, AB, AAA, ABA, AAB, ABB, B, BA, BB, BAA, BBA, BAB, BBB
|
||||
A = p[xi ] + yi
|
||||
AA = p[A ] + zi
|
||||
AB = p[A+1 ] + zi
|
||||
AAA = p[ AA ]
|
||||
ABA = p[ AB ]
|
||||
AAB = p[ AA+1 ]
|
||||
ABB = p[ AB+1 ]
|
||||
|
||||
B = p[xi+1] + yi
|
||||
BA = p[B ] + zi
|
||||
BB = p[B+1 ] + zi
|
||||
BAA = p[ BA ]
|
||||
BBA = p[ BB ]
|
||||
BAB = p[ BA+1 ]
|
||||
BBB = p[ BB+1 ]
|
||||
|
||||
-- Take the weighted average between all 8 unit cube coordinates
|
||||
return self.lerp(w,
|
||||
self.lerp(v,
|
||||
self.lerp(u,
|
||||
self:grad(AAA,x,y,z),
|
||||
self:grad(BAA,x-1,y,z)
|
||||
),
|
||||
self.lerp(u,
|
||||
self:grad(ABA,x,y-1,z),
|
||||
self:grad(BBA,x-1,y-1,z)
|
||||
)
|
||||
),
|
||||
self.lerp(v,
|
||||
self.lerp(u,
|
||||
self:grad(AAB,x,y,z-1), self:grad(BAB,x-1,y,z-1)
|
||||
),
|
||||
self.lerp(u,
|
||||
self:grad(ABB,x,y-1,z-1), self:grad(BBB,x-1,y-1,z-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
-- Gradient function finds dot product between pseudorandom gradient vector
|
||||
-- and the vector from input coordinate to a unit cube vertex
|
||||
perlin.dot_product = {
|
||||
[0x0]=function(x,y,z) return x + y end,
|
||||
[0x1]=function(x,y,z) return -x + y end,
|
||||
[0x2]=function(x,y,z) return x - y end,
|
||||
[0x3]=function(x,y,z) return -x - y end,
|
||||
[0x4]=function(x,y,z) return x + z end,
|
||||
[0x5]=function(x,y,z) return -x + z end,
|
||||
[0x6]=function(x,y,z) return x - z end,
|
||||
[0x7]=function(x,y,z) return -x - z end,
|
||||
[0x8]=function(x,y,z) return y + z end,
|
||||
[0x9]=function(x,y,z) return -y + z end,
|
||||
[0xA]=function(x,y,z) return y - z end,
|
||||
[0xB]=function(x,y,z) return -y - z end,
|
||||
[0xC]=function(x,y,z) return y + x end,
|
||||
[0xD]=function(x,y,z) return -y + z end,
|
||||
[0xE]=function(x,y,z) return y - x end,
|
||||
[0xF]=function(x,y,z) return -y - z end
|
||||
}
|
||||
function perlin:grad(hash, x, y, z)
|
||||
return self.dot_product[bit32.band(hash,0xF)](x,y,z)
|
||||
end
|
||||
|
||||
-- Fade function is used to smooth final output
|
||||
function perlin.fade(t)
|
||||
return t * t * t * (t * (t * 6 - 15) + 10)
|
||||
end
|
||||
|
||||
function perlin.lerp(t, a, b)
|
||||
return a + t * (b - a)
|
||||
end
|
||||
|
||||
return perlin
|
|
@ -0,0 +1,16 @@
|
|||
core.register_list_command("xray", "Configure X-Ray", "xray_nodes")
|
||||
core.register_list_command("search", "Configure NodeESP", "node_esp_nodes")
|
||||
|
||||
core.register_on_spawn_particle(function(particle)
|
||||
if core.settings:get_bool("noweather") and particle.texture:sub(1, 12) == "weather_pack" then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_play_sound(function(sound)
|
||||
if core.settings:get_bool("noweather") and sound.name == "weather_rain" then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_cheat("NoWeather", "Render", "noweather")
|
|
@ -0,0 +1,48 @@
|
|||
local warp = warp or {set_here = function() return false end}
|
||||
|
||||
local formspec = ""
|
||||
.. "size[11,5.5]"
|
||||
.. "bgcolor[#320000b4;true]"
|
||||
.. "label[4.85,1.35;" .. "You died" .. "]"
|
||||
.. "button_exit[2,3;3,0.5;btn_respawn;" .. "Respawn" .. "]"
|
||||
.. "button_exit[6,3;3,0.5;btn_ghost_mode;" .. "Ghost Mode" .. "]"
|
||||
.. "set_focus[btn_respawn;true]"
|
||||
|
||||
minetest.register_on_death(function()
|
||||
if minetest.settings:get_bool("deathwarp") then
|
||||
local warp_success, warp_msg = warp.set_here("death")
|
||||
if warp_success then
|
||||
minetest.display_chat_message(warp_msg)
|
||||
end
|
||||
end
|
||||
if minetest.settings:get_bool("autorespawn") then
|
||||
minetest.send_respawn()
|
||||
else
|
||||
minetest.show_formspec("respawn:death", formspec)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "respawn:death" then
|
||||
if fields.btn_ghost_mode then
|
||||
minetest.display_chat_message("You are in ghost mode. Use .respawn to Respawn.")
|
||||
else
|
||||
minetest.send_respawn()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("respawn", {
|
||||
description = "Respawn when in ghost mode",
|
||||
func = function()
|
||||
if minetest.localplayer:get_hp() == 0 then
|
||||
minetest.send_respawn()
|
||||
minetest.display_chat_message("Respawned.")
|
||||
else
|
||||
minetest.display_chat_message("You are not in ghost mode.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_cheat("AutoRespawn", "Player", "autorespawn")
|
||||
minetest.register_cheat("DeathWarp", "Player", "deathwarp")
|
|
@ -0,0 +1,4 @@
|
|||
name = respawn
|
||||
author = Fleckenstein
|
||||
description = Extended respawn behaviour
|
||||
optional_depends = warp
|
|
@ -0,0 +1 @@
|
|||
autorespawn (AutoRespawn) bool false
|
|
@ -0,0 +1,204 @@
|
|||
local autoeat = rawget(_G, "autoeat") or {}
|
||||
local storage = minetest.get_mod_storage()
|
||||
local pos1, pos2
|
||||
local min, max = math.min, math.max
|
||||
local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks
|
||||
|
||||
minetest.register_chatcommand("pos1", {
|
||||
description = "Set schematicas position 1 at your current location",
|
||||
func = function()
|
||||
pos1 = vector.round(minetest.localplayer:get_pos())
|
||||
return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("pos2", {
|
||||
description = "Set schematicas position 2 at your current location",
|
||||
func = function()
|
||||
pos2 = vector.round(minetest.localplayer:get_pos())
|
||||
return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("schemesave", {
|
||||
description = "Save a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
if not pos1 or not pos2 then
|
||||
return false, "Position 1 or 2 not set."
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
local lx, ly, lz, hx, hy, hz = min(pos1.x, pos2.x), min(pos1.y, pos2.y), min(pos1.z, pos2.z), max(pos1.x, pos2.x), max(pos1.y, pos2.y), max(pos1.z, pos2.z)
|
||||
|
||||
for x = lx, hx do
|
||||
local rx = x - lx
|
||||
for y = ly, hy do
|
||||
local ry = y - ly
|
||||
for z = lz, hz do
|
||||
local rz = z - lz
|
||||
local node = minetest.get_node_or_nil({x = x, y = y, z = z})
|
||||
if node and node.name ~= "air" then
|
||||
table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
storage:set_string(name, minetest.serialize(data))
|
||||
return true, "Scheme saved successfully as '" .. name .. "'."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemebuild", {
|
||||
description = "Build a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
if not pos1 then
|
||||
return false, "Position 1 not set."
|
||||
end
|
||||
if building then
|
||||
return false, "Still building a scheme. Use .schemeabort to stop it."
|
||||
end
|
||||
local rawdata = storage:get(name)
|
||||
if not rawdata then
|
||||
return false, "Schematica '" .. name .. "' not found."
|
||||
end
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = true, 1, minetest.deserialize(rawdata), vector.new(pos1), false, 0, false
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemerecipe", {
|
||||
description = "Print the recipe for a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
local rawdata = storage:get(name)
|
||||
if not rawdata then
|
||||
return false, "Schematica '" .. name .. "' not found."
|
||||
end
|
||||
local data = minetest.deserialize(rawdata)
|
||||
local sorted = {}
|
||||
for _, d in ipairs(data) do
|
||||
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeresume", {
|
||||
description = "Resume constructing a schematica",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, out_of_blocks = true, false
|
||||
return true, "Resumed."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemepause", {
|
||||
description = "Pause constructing a schematica",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building = false
|
||||
return true, "Paused."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeabort", {
|
||||
description = "Abort constructing a schematica",
|
||||
param = "<name>",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
|
||||
return true, "Aborted."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeskip", {
|
||||
description = "Skip a step in constructing a schematica",
|
||||
param = "<name>",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, build_index = true, build_index + 1
|
||||
return true, "Skipped."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemegetindex", {
|
||||
description = "Output the build index of the schematica",
|
||||
func = function()
|
||||
return build_index and true or false, build_index
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemesetindex", {
|
||||
description = "Set the build index of the schematica",
|
||||
param = "<index>",
|
||||
func = function(param)
|
||||
local index = tonumber(param)
|
||||
if not index then return false, "Invalid usage." end
|
||||
build_index = index
|
||||
return true, "Index Changed"
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if building and not autoeat.eating then
|
||||
local data = build_data[build_index]
|
||||
if not data then
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
|
||||
minetest.display_chat_message("Completed Schematica.")
|
||||
return
|
||||
end
|
||||
local pos, node = vector.add(build_pos, data.pos), data.node
|
||||
if just_placed_node then
|
||||
local map_node = minetest.get_node_or_nil(pos)
|
||||
if map_node and map_node.name == node then
|
||||
build_index = build_index + 1
|
||||
just_placed_node = false
|
||||
else
|
||||
failed_count = failed_count + 1
|
||||
end
|
||||
if failed_count < 10 then
|
||||
return
|
||||
end
|
||||
end
|
||||
failed_count = 0
|
||||
local new_index
|
||||
local inventory = minetest.get_inventory("current_player").main
|
||||
for index, stack in ipairs(inventory) do
|
||||
if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
|
||||
new_index = index - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
if not new_index then
|
||||
if not out_of_blocks then
|
||||
minetest.display_chat_message("Out of blocks for schematica. Missing ressource: '" .. node .. "'. It will resume as soon as you got it or use .schemeskip to skip it.")
|
||||
minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
|
||||
end
|
||||
out_of_blocks = true
|
||||
return
|
||||
end
|
||||
if out_of_blocks then
|
||||
minetest.send_chat_message("[Schematicas] Resuming.")
|
||||
end
|
||||
out_of_blocks = false
|
||||
minetest.localplayer:set_wield_index(new_index)
|
||||
minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
|
||||
minetest.place_node(pos)
|
||||
just_placed_node = true
|
||||
if build_index % 250 == 0 then
|
||||
minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
name = schematicas
|
||||
description = Save structures and recreate them automatically in survival.
|
||||
author = Fleckenstein
|
||||
optional_depends = autoeat
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Benjamin Fleming
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,59 @@
|
|||
# CSM DTE
|
||||
## Client Side Mod Designing & Testing Environment
|
||||
An advanced, ingame lua and formspec editor for minetest.
|
||||
|
||||
This can be used for creating, testing and using CSMs without reloading the game, and without the game crashing.
|
||||
This is also the easiest way to create advanced formspecs.
|
||||
It was tested with multiple CSMs from the minetest forums, and they all worked. (actually in the current version, a few things might not work, but they will be fixed in the future)
|
||||
|
||||
CSMs can be created, or pasted in, and they should work the same as they would normaly, except errors won't crash the game!
|
||||
|
||||
functions that are registered with minetest can be put in a function `safe(func)` to output errors to the UI when minetest calls them
|
||||
|
||||
scripts can be put in startup to run them automatically when the game loads. errors are also put in the UI
|
||||
|
||||
screenshots:
|
||||
![lua editor](preview_1.png)
|
||||
![formspec editor](preview_2.png)
|
||||
|
||||
## FEATURES:
|
||||
lua editor:
|
||||
- print function
|
||||
- coloured error output
|
||||
- multiple files
|
||||
- file creation and deletion
|
||||
- safe function execution
|
||||
- automatically run files at startup
|
||||
|
||||
formspec editor:
|
||||
- every widget is available
|
||||
- widgets are easy to edit
|
||||
- formspec preview, shows what it will look like
|
||||
- export as a function with parameters
|
||||
- export as a string
|
||||
- and a whole bunch of fancy stuff
|
||||
|
||||
## To Use:
|
||||
- use the command `.dte` to open the editor
|
||||
- select the `lua editor` tab to run and edit CSMs
|
||||
- select the `formspec editor` tab to create a formspec
|
||||
- select the `files` tab to open, create, and delete files
|
||||
- select the `startup` tab to select lua files to run when the game loads
|
||||
|
||||
## How to install
|
||||
- make sure you have client modding enabled (search for `client modding` in advanced settings, and set it to true)
|
||||
- download and extract the zip file into `clientmods\csm_dte` or paste the `init.lua` file into it.
|
||||
- add `load_mod_csm_dte = true` to the `clientmods\mods.conf` file
|
||||
- join a game or server, and it should work!
|
||||
|
||||
## Editing the files
|
||||
### - if you do not wan't to edit the program, the `development` folder can be deleted!
|
||||
when editing the program, it is easier to edit the smaller files found inside the `development` folder.
|
||||
these can be run as seperate CSMs for testing (I recomend disabling `csm_dte`)
|
||||
to join the together, copy the lua editor into `csm_dte/init.lua` and copy the formspec editor (from EDITOR START to EDITOR END) into the "PASTE FORMSPEC EDITOR HERE" section
|
||||
|
||||
### TODO:
|
||||
- make all functions work after the game has been loaded
|
||||
- add a UI to unregister functions which were registered from a program
|
||||
- add a lua console
|
||||
- import ui strings into the editor (?)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,492 @@
|
|||
local data = { -- window size
|
||||
width = 15,
|
||||
height = 10,
|
||||
|
||||
}
|
||||
local form_esc = minetest.formspec_escape -- shorten the function
|
||||
|
||||
local modstorage = core.get_mod_storage()
|
||||
|
||||
|
||||
local function create_tabs(selected)
|
||||
return "tabheader[0,0;_option_tabs_;" ..
|
||||
" LUA EDITOR ,FORMSPEC EDITOR, LUA CONSOLE , FILES , STARTUP , FUNCTIONS , HELP ;"..selected..";;]"
|
||||
end
|
||||
|
||||
local function copy_table(table)
|
||||
local new = {}
|
||||
for i, v in pairs(table) do
|
||||
if type(v) == "table" then
|
||||
v = copy_table(v)
|
||||
end
|
||||
new[i] = v
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
|
||||
----------
|
||||
-- LOAD AND DEFINE STUFF - global stuff is accissible from the UI
|
||||
----------
|
||||
|
||||
local split = function (str, splitter) -- a function to split a string into a list. "\" before the splitter makes it ignore it (usefull for minetests formspecs)
|
||||
local result = {""}
|
||||
for i=1, str:len() do
|
||||
char = string.sub(str, i, i)
|
||||
if char == splitter and string.sub(str, i-1, i-1) ~= "\\" then
|
||||
table.insert(result, "")
|
||||
else
|
||||
result[#result] = result[#result]..char
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
local output = {} -- the output for errors, prints, etc
|
||||
|
||||
local saved_file = modstorage:get_string("_lua_saved") -- remember what file is currently being edited
|
||||
if saved_file == "" then
|
||||
saved_file = false -- if the file had no save name (it was still saved)
|
||||
end
|
||||
|
||||
|
||||
local lua_startup = split(modstorage:get_string("_lua_startup"), ",") -- the list of scripts to run at startup
|
||||
|
||||
local lua_files = split(modstorage:get_string("_lua_files_list"), ",") -- the list of names of all saved files
|
||||
|
||||
local ui_files = split(modstorage:get_string("_UI_files_list"), ",") -- UI files list
|
||||
|
||||
local reg_funcs = {formspec_input={}, chatcommands={}, on_connect={}, joinplayer={}, sending_chat_message={}, recieving_chat_message={}}
|
||||
|
||||
|
||||
local selected_files = {0, 0}
|
||||
|
||||
|
||||
minetest.register_on_connect(function() -- some functions don't work after startup. this tries to replace them
|
||||
|
||||
minetest.get_mod_storage = function()
|
||||
return modstorage
|
||||
end
|
||||
|
||||
core.get_mod_storage = function()
|
||||
return modstorage
|
||||
end
|
||||
|
||||
-- show formspec
|
||||
|
||||
end) -- add whatever functions don't work after startup to here (if possible)
|
||||
|
||||
|
||||
----------
|
||||
-- FUNCTIONS FOR UI
|
||||
----------
|
||||
|
||||
function print(...) -- replace print to output into the UI. (doesn't refresh untill the script has ended)
|
||||
params = {...}
|
||||
if #params == 1 then
|
||||
local str = params[1]
|
||||
if type(str) ~= "string" then
|
||||
str = dump(str)
|
||||
end
|
||||
table.insert(output, "")
|
||||
for i=1, str:len() do
|
||||
char = string.sub(str, i, i)
|
||||
if char == "\n" then
|
||||
table.insert(output, "") -- split multiple lines over multiple lines. without this, text with line breaks would not display properly
|
||||
else
|
||||
output[#output] = output[#output]..char
|
||||
end
|
||||
end
|
||||
else
|
||||
for i, v in pairs(params) do
|
||||
print(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function safe(func) -- run a function without crashing the game. All errors are displayed in the UI.
|
||||
f = function(...) -- This can be used for functions being registered with minetest, like "minetest.register_chat_command()"
|
||||
status, out = pcall(func, ...)
|
||||
if status then
|
||||
return out
|
||||
else
|
||||
table.insert(output, "#ff0000Error: "..out)
|
||||
minetest.debug("Error (func): "..out)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
|
||||
----------
|
||||
-- CODE EXECUTION
|
||||
----------
|
||||
|
||||
local function run(code, name) -- run a script
|
||||
if name == nil then
|
||||
name = saved_file
|
||||
end
|
||||
status, err = pcall(loadstring(code)) -- run
|
||||
if status then
|
||||
if saved_file == false then
|
||||
table.insert(output, "#00ff00finished") -- display that the script ran without errors
|
||||
else
|
||||
table.insert(output, "#00ff00"..name..": finished") -- display which script, if it was saved
|
||||
end
|
||||
else
|
||||
if err == "attempt to call a nil value" then
|
||||
err = "Syntax Error"
|
||||
end
|
||||
if saved_file == false then
|
||||
table.insert(output, "#ff0000Error: "..err) -- display errors
|
||||
minetest.log("Error (unsaved): "..err)
|
||||
else
|
||||
table.insert(output, "#ff0000"..name..": Error: "..err)
|
||||
minetest.log("Error ("..name.."): "..err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_startup() -- ran on startup. Runs all scripts registered for startup
|
||||
for i, v in pairs(lua_startup) do
|
||||
if v ~= "" then
|
||||
run(modstorage:get_string("_lua_file_"..v, v), v) -- errors still get displayed in the UI
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on_startup()
|
||||
|
||||
|
||||
----------
|
||||
-- FILE READING AND SAVING
|
||||
----------
|
||||
|
||||
local function load_lua() -- returns the contents of the file currently being edited
|
||||
if saved_file == false then
|
||||
return modstorage:get_string("_lua_temp") -- unsaved files are remembered (get saved on UI reloads - when clicking on buttons)
|
||||
else
|
||||
return modstorage:get_string("_lua_file_"..saved_file)
|
||||
end
|
||||
end
|
||||
|
||||
local function save_lua(code) -- save a file
|
||||
if saved_file == false then
|
||||
modstorage:set_string("_lua_temp", code)
|
||||
else
|
||||
modstorage:set_string("_lua_file_"..saved_file, code)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
----------
|
||||
-- FORM DEFINITIONS
|
||||
----------
|
||||
|
||||
|
||||
local function startup_form() -- the formspec for adding or removing files for startup
|
||||
local startup_str = ""
|
||||
for i, v in pairs(lua_startup) do
|
||||
if i ~= 1 then startup_str = startup_str.."," end
|
||||
startup_str = startup_str .. form_esc(v)
|
||||
end
|
||||
local files_str = ""
|
||||
for i, v in pairs(lua_files) do
|
||||
if i ~= 1 then files_str = files_str.."," end
|
||||
files_str = files_str .. form_esc(v)
|
||||
end
|
||||
|
||||
local form = ""..
|
||||
"size["..data.width..","..data.height.."]" ..
|
||||
"label[0,0.1;Startup Items:]"..
|
||||
"label["..data.width/2 ..",0.1;File List:]"..
|
||||
"textlist[0,0.5;"..data.width/2-0.1 ..","..data.height-1 ..";starts;"..startup_str.."]"..
|
||||
"textlist["..data.width/2 ..",0.5;"..data.width/2-0.1 ..","..data.height-1 ..";chooser;"..files_str.."]"..
|
||||
"label[0," .. data.height-0.3 .. ";double click items to add or remove from startup]"..
|
||||
|
||||
"" .. create_tabs(5)
|
||||
return form
|
||||
end
|
||||
|
||||
|
||||
local function lua_editor() -- the main formspec for editing
|
||||
|
||||
local output_str = "" -- convert the output to a string
|
||||
for i, v in pairs(output) do
|
||||
if output_str:len() > 0 then output_str = output_str .. "," end
|
||||
output_str = output_str .. form_esc(v)
|
||||
end
|
||||
|
||||
local code = form_esc(load_lua())
|
||||
|
||||
-- create the form
|
||||
local form = ""..
|
||||
"size["..data.width..","..data.height.."]" ..
|
||||
"textarea[0.3,0.1;"..data.width ..","..data.height-3 ..";editor;Lua editor;"..code.."]"..
|
||||
"button[0," .. data.height-3.5 .. ";1,0;run;RUN]"..
|
||||
"button[1," .. data.height-3.5 .. ";1,0;clear;CLEAR]"..
|
||||
"button[2," .. data.height-3.5 .. ";1,0;save;SAVE]"..
|
||||
"textlist[0,"..data.height-3 ..";"..data.width-0.2 ..","..data.height-7 ..";output;"..output_str..";".. #output .."]"..
|
||||
|
||||
"" .. create_tabs(1)
|
||||
return form
|
||||
end
|
||||
|
||||
|
||||
local function file_viewer() -- created with the formspec editor!
|
||||
local lua_files_item_str = ""
|
||||
for i, item in pairs(lua_files) do
|
||||
if i ~= 1 then lua_files_item_str = lua_files_item_str.."," end
|
||||
lua_files_item_str = lua_files_item_str .. form_esc(item)
|
||||
end
|
||||
|
||||
local ui_select_item_str = ""
|
||||
for i, item in pairs(ui_files) do
|
||||
if i ~= 1 then ui_select_item_str = ui_select_item_str.."," end
|
||||
ui_select_item_str = ui_select_item_str .. form_esc(item)
|
||||
end
|
||||
|
||||
local form = "" ..
|
||||
"size["..data.width..","..data.height.."]" ..
|
||||
"textlist[-0.2,0.2;"..data.width/2.02- -0.2 ..","..data.height- 1 ..";lua_select;"..lua_files_item_str.."]" ..
|
||||
"label[-0.2,-0.2;LUA FILES]" ..
|
||||
"field[0.1,"..data.height- 0.2 ..";3,1;new_lua;NEW;]" ..
|
||||
"field_close_on_enter[new_lua;false]" ..
|
||||
"button[2.6,"..data.height- 0.5 ..";0.5,1;add_lua;+]" ..
|
||||
"textlist["..data.width/1.97 ..",0.2;"..data.width- 0-(data.width/1.97) ..","..data.height- 1 ..";ui_select;"..ui_select_item_str.."]" ..
|
||||
"label["..data.width/1.96 ..",-0.2;FORMSPEC FILES]" ..
|
||||
"field["..data.width- 2.8 ..","..data.height- 0.2 ..";3,1;new_ui;NEW;]" ..
|
||||
"field_close_on_enter[new_ui;false]" ..
|
||||
"button["..data.width- 0.3 ..","..data.height- 0.5 ..";0.5,1;add_ui;+]" ..
|
||||
"label["..data.width/2.4 ..","..data.height- 0.8 ..";Double click a file to open it]" ..
|
||||
"button[3.1,"..data.height- 0.5 ..";1.1,1;del_lua;DELETE]" ..
|
||||
"button["..data.width- 4.2 ..","..data.height- 0.5 ..";1.1,1;del_ui;DELETE]" ..
|
||||
"" .. create_tabs(4)
|
||||
|
||||
return form
|
||||
end
|
||||
|
||||
|
||||
----------
|
||||
-- FUNCTIONALITY
|
||||
----------
|
||||
|
||||
minetest.register_on_formspec_input(function(formname, fields)
|
||||
|
||||
-- EDITING PAGE
|
||||
----------
|
||||
if formname == "lua:editor" then
|
||||
if fields.run then --[RUN] button
|
||||
save_lua(fields.editor)
|
||||
run(fields.editor)
|
||||
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
|
||||
elseif fields.save then --[SAVE] button
|
||||
if saved_file == false then
|
||||
modstorage:set_string("_lua_temp", fields.editor)
|
||||
else
|
||||
modstorage:set_string("_lua_file_"..saved_file, fields.editor)
|
||||
end
|
||||
|
||||
elseif fields.clear then --[CLEAR] button
|
||||
output = {}
|
||||
save_lua(fields.editor)
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
end
|
||||
|
||||
-- STARTUP EDITOR
|
||||
----------
|
||||
elseif formname == "lua:startup" then -- double click a file to remove it from the list
|
||||
if fields.starts then
|
||||
local select = {["type"] = string.sub(fields.starts, 1, 3), ["row"] = tonumber(string.sub(fields.starts, 5, 5))}
|
||||
if select.type == "DCL" then
|
||||
table.remove(lua_startup, select.row)
|
||||
local startup_str = ""
|
||||
for i, v in pairs(lua_startup) do
|
||||
if v ~= "" then
|
||||
startup_str = startup_str..v..","
|
||||
end
|
||||
end
|
||||
modstorage:set_string("_lua_startup", startup_str)
|
||||
minetest.show_formspec("lua:startup", startup_form())
|
||||
end
|
||||
|
||||
elseif fields.chooser then -- double click a file to add it to the list
|
||||
local select = {["type"] = string.sub(fields.chooser, 1, 3), ["row"] = tonumber(string.sub(fields.chooser, 5, 5))}
|
||||
if select.type == "DCL" then
|
||||
table.insert(lua_startup, lua_files[select.row])
|
||||
local startup_str = ""
|
||||
for i, v in pairs(lua_startup) do
|
||||
if v ~= "" then
|
||||
startup_str = startup_str..v..","
|
||||
end
|
||||
end
|
||||
modstorage:set_string("_lua_startup", startup_str)
|
||||
minetest.show_formspec("lua:startup", startup_form())
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
|
||||
---------- ----------
|
||||
-- PASTE FORMSPEC EDITOR HERE --
|
||||
---------- ----------
|
||||
|
||||
|
||||
--
|
||||
|
||||
|
||||
---------- ----------
|
||||
-- PASTE FORMSPEC EDITOR HERE --
|
||||
---------- ----------
|
||||
|
||||
|
||||
|
||||
|
||||
----------
|
||||
-- UI FUNCTIONALITY
|
||||
----------
|
||||
|
||||
minetest.register_on_formspec_input(function(formname, fields)
|
||||
-- FILE VIEWER
|
||||
----------
|
||||
if formname == "files:viewer" then
|
||||
if fields.del_lua then
|
||||
name = lua_files[selected_files[1] ]
|
||||
table.remove(lua_files, selected_files[1])
|
||||
files_str = ""
|
||||
for i, v in pairs(lua_files) do
|
||||
if v ~= "" then
|
||||
files_str = files_str..v.."," -- remove the file from the list
|
||||
end
|
||||
end
|
||||
|
||||
if name == saved_file then -- clear the editing area if the file was loaded
|
||||
saved_file = false
|
||||
modstorage:set_string("_lua_saved", "")
|
||||
save_lua("")
|
||||
end
|
||||
|
||||
modstorage:set_string("_lua_files_list", files_str)
|
||||
minetest.show_formspec("files:viewer", file_viewer())
|
||||
|
||||
elseif fields.del_ui then
|
||||
name = ui_files[selected_files[2] ]
|
||||
table.remove(ui_files, selected_files[2])
|
||||
files_str = ""
|
||||
for i, v in pairs(ui_files) do
|
||||
if v ~= "" then
|
||||
files_str = files_str..v.."," -- remove the file from the list
|
||||
end
|
||||
end
|
||||
|
||||
if name == current_ui_file then -- clear the editing area if the file was loaded
|
||||
load_UI("new")
|
||||
end
|
||||
|
||||
modstorage:set_string("_UI_files_list", files_str)
|
||||
minetest.show_formspec("files:viewer", file_viewer())
|
||||
|
||||
elseif fields.lua_select then -- click on a file to select it, double click to open it
|
||||
local index = tonumber(string.sub(fields.lua_select, 5))
|
||||
if string.sub(fields.lua_select, 1, 3) == "DCL" then
|
||||
saved_file = lua_files[index]
|
||||
|
||||
modstorage:set_string("_lua_saved", saved_file)
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
else
|
||||
selected_files[1] = index
|
||||
minetest.show_formspec("files:viewer", file_viewer())
|
||||
end
|
||||
|
||||
elseif fields.ui_select then -- click on a file to select it, double click to open it
|
||||
local index = tonumber(string.sub(fields.ui_select, 5))
|
||||
if string.sub(fields.ui_select, 1, 3) == "DCL" then
|
||||
load_UI(ui_files[index])
|
||||
reload_ui()
|
||||
else
|
||||
selected_files[2] = index
|
||||
minetest.show_formspec("files:viewer", file_viewer())
|
||||
end
|
||||
|
||||
elseif fields.key_enter_field == "new_lua" or fields.add_lua then
|
||||
local exist = false
|
||||
for i, v in pairs(lua_files) do
|
||||
if v == fields.new_lua then
|
||||
exist = true
|
||||
selected_files[1] = i
|
||||
end
|
||||
end
|
||||
if not exist then
|
||||
table.insert(lua_files, fields.new_lua)
|
||||
selected_files[1] = #lua_files
|
||||
|
||||
files_str = ""
|
||||
for i, v in pairs(lua_files) do
|
||||
if v ~= "" then
|
||||
files_str = files_str..v..","
|
||||
end
|
||||
end
|
||||
modstorage:set_string("_lua_files_list", files_str)
|
||||
saved_file = fields.new_lua
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
end
|
||||
|
||||
elseif fields.key_enter_field == "new_ui" or fields.add_ui then
|
||||
local exist = false
|
||||
for i, v in pairs(ui_files) do
|
||||
if v == fields.new_ui then
|
||||
exist = true
|
||||
selected_files[2] = i
|
||||
end
|
||||
end
|
||||
if not exist then
|
||||
table.insert(ui_files, fields.new_ui)
|
||||
selected_files[2] = #ui_files
|
||||
|
||||
files_str = ""
|
||||
for i, v in pairs(ui_files) do
|
||||
if v ~= "" then
|
||||
files_str = files_str..v..","
|
||||
end
|
||||
end
|
||||
modstorage:set_string("_UI_files_list", files_str)
|
||||
load_UI(fields.new_ui)
|
||||
reload_ui()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fields._option_tabs_ then
|
||||
if fields._option_tabs_ == "1" then
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
elseif fields._option_tabs_ == "2" then
|
||||
reload_ui()
|
||||
elseif fields._option_tabs_ == "4" then
|
||||
minetest.show_formspec("files:viewer", file_viewer())
|
||||
elseif fields._option_tabs_ == "5" then
|
||||
minetest.show_formspec("lua:startup", startup_form())
|
||||
else
|
||||
minetest.show_formspec("lua:unknown",
|
||||
"size["..data.width..","..data.height.."]label[1,1;COMING SOON]"..create_tabs(fields._option_tabs_))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
----------
|
||||
-- REGISTER COMMAND
|
||||
----------
|
||||
core.register_chatcommand("dte", { -- register the chat command
|
||||
description = core.gettext("open a lua IDE"),
|
||||
func = function(parameter)
|
||||
minetest.show_formspec("lua:editor", lua_editor())
|
||||
end,
|
||||
})
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
Loading…
Reference in New Issue