Add files via upload

master
AiTechEye 2022-07-13 18:34:29 +02:00 committed by GitHub
parent 9764467039
commit 149a436400
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 180 additions and 478 deletions

View File

@ -1,494 +1,196 @@
map = {
maps = {
user={},
regimgs={},
shortcut_textures = {
["allfaces_optional"] = "map_l.png",
["default_water.png"] = "map_w.png",
["default_stone.png"] = "map_s.png",
["default_grass.png"] = "map_g.png",
["default_dirt.png"] = "map_d.png",
["default_cloud.png"] = "map_c.png",
["default_sand.png"] = "map_a.png",
["default_snow.png"] = "map_a.png",
["default_dry_grass.png"] = "map_a.png",
},
accepted_drawtypes = {
allfaces_optional=true,
glasslike=true,
normal=true,
liquid=true,
flowingliquid=true,
maps={
["tutorial"]={
info = "Tutorials",
image="default_craftguide.png",
pos={x=0,y=28501,z=0},
size={y=51,x=133,z=100},
--locked=true,
hide_items = true,
singleplayer=true,
on_enter=function(player)
if default.storage:get_int("Tutorials") == 0 then
default.storage:set_int("Tutorials",1)
nodeextractor.set({x=0,y=28501,z=0},minetest.get_modpath("maps").."/nodeextractor/".."maps_tutorial.exexn",true)
end
minetest.after(0.1, function(player)
player:set_pos({x=60,y=28531,z=42})
end,player)
end,
on_exit=function(player)
end,
on_die=function(player)
end,
on_respawn=function(player)
player:set_pos({x=60,y=28531,z=42})
end,
},
}
}
minetest.register_craft({
output="map:workbench",
recipe={
{"group:stick","default:coal_lump","default:gold_ingot"},
{"group:wood","group:wood","group:wood"},
{"group:wood","group:metalstick","group:wood"},
},
})
dofile(minetest.get_modpath("maps") .. "/items.lua")
minetest.register_node("map:workbench", {
description = "Map workbench",
tiles={"default_wood.png^map_map.png","default_wood.png","default_wood.png",},
groups = {choppy=3,oddly_breakable_by_hand=3,flammable=2,used_by_npc=1},
sounds = default.node_sound_wood_defaults(),
paramtype = "light",
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-0.5, 0.125, -0.5, 0.5, 0.1875, 0.5},
{-0.5, -0.5, -0.5, -0.4375, 0.125, -0.4375},
{0.4375, -0.5, -0.5, 0.5, 0.125, -0.4375},
{0.4375, -0.5, 0.4375, 0.5, 0.125, 0.5},
{-0.5, -0.5, 0.4375, -0.4375, 0.125, 0.5},
}
},
on_construct=function(pos,gen,lock)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("input_dye", 1)
inv:set_size("input_paper", 1)
inv:set_size("output", 1)
meta:set_string("formspec",
"size[8,5]" ..
"listcolors[#77777777;#777777aa;#000000ff]"..
"item_image[2,0;1,1;default:dye]" ..
"item_image[3,0;1,1;default:paper]" ..
"item_image[5,0;1,1;map:map]" ..
(lock and "image_button[6,0;1,1;synth_"..(lock == 0 and "no" or "").."lock.png;lock"..lock..";]" or "") ..
"list[context;input_dye;2,0;1,1;]" ..
"list[current_player;main;0,1.3;8,4;]" ..
"list[context;input_paper;3,0;1,1;]" ..
"list[context;output;5,0;1,1;]" ..
"listring[current_player;main]" ..
"listring[current_name;input_paper]" ..
(gen and "image_button[4,0;1,1;map_arrow.png;gen;]" or "")
)
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.get_meta(pos):get_int("running") == 0 and (listname=="input_paper" and stack:get_name() == "default:paper" or listname=="input_dye" and stack:get_name() == "default:dye" or listname=="output" and stack:get_name() == "map:map") then
return stack:get_count()
end
return 0
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
return 0
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local m = minetest.get_meta(pos)
if m:get_int("running") == 0 then
local inv = m:get_inventory()
local ab = inv:get_stack("input_paper",1):get_name() == "default:paper" and inv:get_stack("input_dye",1):get_name() == "default:dye" and inv:get_stack("output",1):get_count() == 0
local ms = inv:get_stack("output",1)
local lock = ms:get_name() == "map:map" and ms:get_meta():get_int("lock") or nil
minetest.registered_items["map:workbench"].on_construct(pos,ab,lock)
end
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local m = minetest.get_meta(pos)
if m:get_int("running") == 0 then
local inv = m:get_inventory()
local lock
if listname == "output" then
m:set_string("infotext","")
else
local ms = inv:get_stack("output",1)
lock = ms:get_name() == "map:map" and ms:get_meta():get_int("lock") or nil
end
local ab = inv:get_stack("input_paper",1):get_name() == "default:paper" and inv:get_stack("input_dye",1):get_name() == "default:dye" and inv:get_stack("output",1):get_count() == 0
minetest.registered_items["map:workbench"].on_construct(pos,ab,lock)
end
end,
can_dig = function(pos, player)
local m = minetest.get_meta(pos)
local inv = m:get_inventory()
return m:get_int("running") == 0 and inv:is_empty("input_paper") and inv:is_empty("input_dye") and inv:is_empty("output")
end,
on_punch = function(pos, node, player, itemstack, pointed_thing)
local m = minetest.get_meta(pos)
if m:get_int("running") ~= 0 and not minetest.get_node_timer(pos):is_started() then
minetest.get_node_timer(pos):start(0.1)
end
end,
on_receive_fields=function(pos, formname, pressed, sender)
local m = minetest.get_meta(pos)
local inv = m:get_inventory()
if pressed.lock0 then
local item = inv:get_stack("output",1)
item:get_meta():set_int("lock",1)
inv:set_stack("output",1,item)
minetest.registered_items["map:workbench"].on_construct(pos,nil,1)
elseif pressed.lock1 then
local item = inv:get_stack("output",1)
item:get_meta():set_int("lock",0)
inv:set_stack("output",1,item)
minetest.registered_items["map:workbench"].on_construct(pos,nil,0)
elseif pressed.gen then
local paper = inv:get_stack("input_paper",1)
local dye = inv:get_stack("input_dye",1)
paper:take_item()
dye:take_item()
inv:set_stack("input_paper",1,paper)
inv:set_stack("input_dye",1,dye)
minetest.registered_items["map:workbench"].on_construct(pos)
m:set_string("parts","")
m:set_int("index",1)
m:set_int("running",1)
minetest.get_node_timer(pos):start(0.1)
end
end,
on_timer = function (pos, elapsed)
local rad = 5
local ds = rad*2
local s = 0.4
local m = minetest.get_meta(pos)
local parts
if m:get_string("parts") == "" then
parts = {}
for x=-rad,rad do
for z=-rad,rad do
table.insert(parts,{lpos={x=-x*s,y=-z*s,z=-0.01},pos={x=pos.x+(x*ds),y=pos.y,z=pos.z+(z*ds)}})
end
end
m:set_string("parts",minetest.serialize(parts))
player_style.register_button({
name="special",
image="map_map.png",
type="image",
info="Abilities",
action=function(user)
local name = user:get_player_name()
local inv = player_style.players[name].inv
if inv.adds["maps_exit"] then
minetest.chat_send_player(name,"You have to exit the current map first")
else
parts = minetest.deserialize(m:get_string("parts"))
end
local n = #parts
local stat = m:get_int("running")
local index = m:get_int("index")
m:set_string("infotext",(math.floor((100/n * index)*10)*0.1).."% ("..index.."/"..n.." images)")
if index <= n then
local p = parts[index]
local t = map.generate_texture(rad,p.pos)
if t then
m:set_string("texture"..index,t)
m:set_int("index",index+1)
end
else
local inv = m:get_inventory()
if stat == 1 then
local textures = {}
for i=1,n do
table.insert(textures,m:get_string("texture"..i))
end
local pp = minetest.pos_to_string(pos)
local item = ItemStack("map:map")
local meta = item:get_meta()
meta:set_string("pos",pp)
meta:set_string("textures",minetest.serialize(textures))
meta:set_int("index",1)
meta:set_string("description","Map "..pp)
inv:set_stack("output",1,item)
m:set_int("running",2)
else
m:set_string("infotext","100%")
for i=1,n do
m:set_string("texture"..i,"")
end
m:set_int("running",0)
minetest.registered_items["map:workbench"].on_construct(pos,nil,0)
return false
end
end
return true
end
})
minetest.register_tool("map:map", {
description = "Map",
groups = {flammable=3,not_in_creative_inventory=1},
inventory_image = "map_map.png",
on_drop=function(itemstack, droper, pos)
end,
on_use=function(itemstack, user, pointed_thing)
map.user[user] = map.user[user] or {}
local p = map.user[user]
if p.ob and p.ob:get_luaentity() then
p.ob:remove()
p.ob = nil
return
end
local m = itemstack:get_meta()
local index = m:get_int("index")
if index == 0 then
minetest.chat_send_player(user:get_player_name(),"The map is corrupted")
return
end
local pos = user:get_pos()
p.ob = minetest.add_entity(pos,"map:map")
local en = p.ob:get_luaentity()
en.user = user
en.posid = m:get_string("pos")
en.pos = minetest.string_to_pos(m:get_string("pos"))
en.textures = minetest.deserialize(m:get_string("textures"))
en.item = itemstack
en.index = index
en.lock = m:get_int("lock") == 1
p.ob:set_attach(user, "",{x=0, y=9, z=3}, {x=0, y=0,z=0},true)
end
})
minetest.register_entity("map:part",{
physical = false,
pointable=false,
visual="mesh",
mesh="map_map.obj",
backface_culling=false,
textures = {"default_air.png"},
static_save = false,
decoration=true,
time = 5,
on_step=function(self, dtime)
if not self.object:get_attach() then
self.object:remove()
end
end,
})
minetest.register_entity("map:map",{
physical = false,
pointable=false,
visual="mesh",
visual_size = {x=0.75,y=0.75,z=1},
mesh="map_map.obj",
backface_culling=false,
textures = {"map_map.png"},
static_save = false,
decoration=true,
on_activate=function(self,staticdata,dtime_s)
self.timer = 1
self.timer2 = 0
self.time = 0
self.saver = 0
self.parts ={}
end,
load=function(self)
self.time = 1000
local pos = self.user:get_pos()
local rad = 5
local s = 0.8
local ds = rad*2
local i = 0
for x=-rad,rad do
for z=-rad,rad do
table.insert(self.parts,{lpos={x=-x*s,y=-z*s,z=-0.01},pos={x=self.pos.x+(x*ds),y=self.pos.y,z=self.pos.z+(z*ds)}})
end
end
for i=1,#self.parts do
local t = self.textures[i]
local p = self.parts[i]
p.ob = minetest.add_entity(pos,"map:part")
p.ob:set_properties({visual_size = {x=0.1*s,y=0.1*s,z=1}})
p.ob:set_attach(self.object, "",p.lpos, {x=0, y=0,z=0},true)
p.ob:set_properties({textures={t}})
end
if self.lock then
local l = minetest.add_entity(pos,"map:part")
l:set_properties({visual_size = {x=0.1,y=0.1,z=1}})
l:set_attach(self.object, "",{x=4.8, y=4.8,z=-0.0105}, {x=0, y=0,z=0},true)
l:set_properties({textures={"synth_lock.png"}})
end
self.time = 0.1
self.loaded = true
end,
on_step=function(self, dtime)
self.timer = self.timer +dtime
if self.timer > self.time then
self.timer = 0
if not self.loaded then
self:load()
else
self:update(self)
end
end
end,
update=function(self,load)
if not (self.object:get_attach() and self.user and self.pos) then
self.object:remove()
else
local pos = self.user:get_pos()
--cursor
if not self.cursor then
self.cursor = minetest.add_entity(pos,"map:part")
self.cursor:set_properties({visual_size = {x=0.04,y=0.04,z=1},textures={"map_cursor.png"}})
end
local x = self.pos.x-pos.x
local z = self.pos.z-pos.z
local ux = math.abs(x) < 55 and x*0.08055 or (55*x/math.abs(x))*0.08055
local uz = math.abs(z) < 55 and z*0.08055 or (55*z/math.abs(z))*0.08055
self.cursor:set_attach(self.object, "",{x=ux,y=uz,z=-0.011}, {x=0, y=0,z=(self.user:get_look_horizontal() * 180 / math.pi)+180},true)
--map attach
local lv = self.user:get_look_vertical()
lv = lv < 1 and lv > 0 and lv or lv > 1 and 1 or lv < 0 and 0
self.object:set_attach(self.user, "",{x=0, y=9.5+(lv*3), z=3}, {x=(lv * 180 / math.pi), y=0,z=0},true)
--map update
self.timer2 = self.timer2 + 0.1
if self.lock or self.timer2 < 1 then
return
end
self.timer2 = 0
local rad = 5
if self.index > #self.parts then
self.index = 1
end
local p = self.parts[self.index]
local t = map.generate_texture(rad,p.pos)
if not t then
return
end
self.saver = self.saver +1
self.textures[self.index] = t
local itname = self.user:get_wielded_item():get_name()
if itname == "map:map" then
if self.saver > 10 then
local item = self.user:get_wielded_item()
local meta = item:get_meta()
if meta:get_string("pos") == self.posid then
self.saver = 0
meta:set_string("textures",minetest.serialize(self.textures))
meta:set_int("index",self.index)
self.user:set_wielded_item(item)
else
self.user = nil
return
end
end
elseif itname ~= "default:telescopic" then
self.user = nil
return
end
p.ob:set_properties({textures={t}})
self.index = self.index +1
maps.show(user)
end
end
})
--minetest.register_chatcommand("t", { --using while testing
-- func = function(name, param)
-- map.t=tonumber(param)
-- end
--})
map.generate_texture=function(rad,pos,maxram)
pos=vector.round(pos)
local image_resolution = 16
local map_size = ((rad*2)*image_resolution)+1
maxram = maxram or 20
local air=minetest.get_content_id("air")
local pos1 = vector.subtract(pos, rad)
local pos2 = vector.add(pos, rad)
local vox = minetest.get_voxel_manip()
local min, max = vox:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge = min, MaxEdge = max})
local data = vox:get_data()
local imgmap = {}
local texture = "[combine:"..map_size.."x"..map_size
for x = -rad,rad do
for z = -rad,rad do
for y = rad,-rad,-1 do
local v = area:index(pos.x+x,pos.y+y,pos.z+z)
local p={x=pos.x+x,y=pos.y+y,z=pos.z+z}
local i = x..","..z
local id = data[v]
if not imgmap[i] and id ~= air then
if maxram < tonumber(memory_mb()) then
print(memory_mb())
goto out
end
local def = default.def(minetest.get_name_from_content_id(id))
local img = ""
local tiles = def.tiles or def.special_tiles or {}
local reg = map.regimgs[def.name]
if reg then
img = reg
elseif def.drawtype == "allfaces_optional" then
img = map.shortcut_textures["allfaces_optional"]
elseif type(tiles[1]) == "string" then
img = tiles[1]
elseif type(tiles) == "table" and type(tiles.tile) == "string" then
img = tiles.tile
end
if img and map.accepted_drawtypes[def.drawtype] then
img = map.shortcut_textures[img] or img
if not reg then
if img:find("%(") then
img = img:sub(1,img:find("%(")-1)
end
if img:find("%[") then
img = img:sub(1,img:find("%^")-1)
if img:find("%[") then
img = ""
end
elseif img:find("%^") then
img = img:gsub("%^","\\%^"):gsub(":","\\:")
end
end
if img ~= "" then
map.regimgs[def.name] = img
imgmap[i] = true
local X = (-rad+x)*image_resolution
local Z = (rad+z)*image_resolution
texture = texture .. ":"..-X..","..Z.."="..img
maps.show=function(player)
minetest.after(0.2, function(player)
local name = player:get_player_name()
local x,y = 0,0
local form = "size[8,8]listcolors[#77777777;#777777aa;#000000ff]"
for i,v in pairs(maps.maps) do
if not (v.singleplayer and minetest.is_singleplayer() == false) then
form = form
.. "image_button["..x..","..y..";1,1;"..(v.image or "map_map.png")..(v.locked and "^default_lock_icon.png" or "")..(v.unable and "^default_cross.png" or "")..";mapsbut_"..i..";]"
.. (v.info and "tooltip[mapsbut_"..i..";"..v.info..(v.singleplayer and "\n(Singleplayer only)" or "").."]" or "")
x = x + 1
if x >= 8 then
x = 0
y = y +1
end
end
end
end
end
end
::out::
if #texture > 65000 then
texture = texture:sub(1,65000)
for i=#texture,1,-1 do
if texture:sub(i-3,i) == ".png" then
texture = texture:sub(1,i)
break
end
end
end
return texture
return minetest.show_formspec(name, "maps",form)
end, player)
end
minetest.register_on_leaveplayer(function(player)
map.user[player] = nil
minetest.register_on_player_receive_fields(function(player, form, pressed)
if form == "maps" then
for i,v in pairs(pressed) do
if i:sub(1,8) == "mapsbut_" then
local b = i:gsub("mapsbut_","")
local map = maps.maps[b]
if not (maps.maps[b].unable or maps.maps[b].locked) then
local m = player:get_meta()
m:set_string("maps_current",b)
maps.set_exit_player(player)
if map.hide_items then
player_style.inventory_handle(player,{hide=true})
if m:get_string("maps_pos") == "" then
m:set_string("maps_pos",minetest.pos_to_string(player:get_pos()))
end
end
player_style.inventory(player)
maps.maps[b].on_enter(player)
minetest.close_formspec(player:get_player_name(),"")
end
end
end
end
end)
minetest.register_on_mods_loaded(function()
for map,m in pairs(maps.maps) do
local p1 = m.pos
local p2 = vector.add(m.pos,m.size)
if not m.pos then
minetest.log("warning","Maps: "..map.." Is missing pos (position/vector)")
maps.maps[map].unable = true
end
if not m.size then
minetest.log("warning","Maps: "..map.." Is missing size (vector)")
maps.maps[map].unable = true
end
if not m.on_enter then
minetest.log("warning","Maps: "..map.." Is missing on_enter (function)")
maps.maps[map].unable = true
end
if not m.on_exit then
minetest.log("warning","Maps: "..map.." Is missing on_exit (function)")
maps.maps[map].unable = true
end
if not m.on_die then
minetest.log("warning","Maps: "..map.." Is missing on_die (function)")
maps.maps[map].unable = true
end
if not m.on_respawn then
minetest.log("warning","Maps: "..map.." Is missing on_respawn (function)")
maps.maps[map].unable = true
end
for i,v in pairs(maps.maps) do
local pos1,pos2 = protect.sort(v.pos,vector.add(v.pos,v.size))
if map ~= i and not maps.maps[map].unable
and (pos1.x <= p2.x and pos2.x >= p1.x)
and (pos1.y <= p2.y and pos2.y >= p1.y)
and (pos1.z <= p2.z and pos2.z >= p1.z) then
minetest.log("error","Maps: "..i.." interacts with "..map)
maps.maps[i].unable = true
end
end
end
end)
minetest.register_on_joinplayer(function(player)
if player:get_meta():get_int("maps_exit") == 1 then
maps.set_exit_player(player)
end
end)
maps.set_exit_player=function(player)
local name = player:get_player_name()
local inv = player_style.players[name].inv
local m = player:get_meta()
inv.adds["maps_exit"] = "image_button[7,1;1,1;map_map.png^default_cross.png;maps_exit;]tooltip[maps_exit;Exit map]"
m:set_int("maps_exit",1)
m:set_int("respawn_disallowed",1)
inv.adds_func["maps_exit"] = function(player)
local m = player:get_meta()
local name = player:get_player_name()
local inv = player_style.players[name].inv
local p = minetest.string_to_pos(m:get_string("maps_pos"))
local map = maps.maps[m:get_string("maps_current")]
if map and map.on_exit then
map.on_exit(player)
end
if p then
player:set_pos(p)
end
inv.adds["maps_exit"] = nil
inv.adds_func["maps_exit"] =nil
m:set_string("maps_pos","")
m:set_int("maps_exit",0)
m:set_int("respawn_disallowed",0)
m:set_string("maps_current","")
player_style.inventory_handle(player,{show=true})
minetest.close_formspec(name,"")
end
end
minetest.register_on_respawnplayer(function(player)
local map = maps.maps[player:get_meta():get_string("maps_current")]
if map then
minetest.after(0, function(player,map)
map.on_respawn(player)
end,player,map)
end
end)
minetest.register_on_dieplayer(function(player)
local map = maps.maps[player:get_meta():get_string("maps_current")]
if map and map.on_die then
map.on_die(player)
end
end)