490 lines
13 KiB
Lua
490 lines
13 KiB
Lua
mt2d={
|
|
timer=0,
|
|
user3d={}, --3d users
|
|
user={}, --users data
|
|
attach={}, --attached objects (pushing them)
|
|
playeranim={
|
|
stand={x=1,y=39,speed=30},
|
|
walk={x=41,y=61,speed=30},
|
|
mine={x=65,y=75,speed=30},
|
|
hugwalk={x=80,y=99,speed=30},
|
|
lay={x=113,y=123,speed=0},
|
|
sit={x=101,y=111,speed=0},
|
|
},
|
|
}
|
|
|
|
dofile(minetest.get_modpath("mt2d") .. "/nodes_items.lua")
|
|
dofile(minetest.get_modpath("mt2d") .. "/entities.lua")
|
|
|
|
minetest.register_privilege("leave2d", {
|
|
description = "Leave Dimension",
|
|
give_to_singleplayer= false,
|
|
})
|
|
minetest.register_on_mods_loaded(function()
|
|
--minetest.after(0.1, function()
|
|
minetest.registered_entities["__builtin:item"].on_activate2=minetest.registered_entities["__builtin:item"].on_activate
|
|
minetest.registered_entities["__builtin:item"].on_activate=function(self, staticdata,time)
|
|
minetest.registered_entities["__builtin:item"].on_activate2(self, staticdata,time)
|
|
minetest.after(0, function(self)
|
|
if self and self.object then
|
|
self.object:set_properties({
|
|
automatic_rotate=0,
|
|
collisionbox={-0.2,-0.2,0,0.2,0.2,0},
|
|
})
|
|
local pos=self.object:get_pos()
|
|
self.object:set_pos({x=pos.x,y=pos.y,z=0})
|
|
end
|
|
end,self)
|
|
return self
|
|
end
|
|
for i, v in pairs(minetest.registered_items) do
|
|
if not v.range or v.range<8 then
|
|
minetest.override_item(i, {range=8})
|
|
end
|
|
end
|
|
for i, v in pairs(minetest.registered_nodes) do
|
|
if v.drawtype~="airlike" and not v.mt2d and v.tiles then
|
|
|
|
local inventory_image=v.inventory_image
|
|
local walkable=v.walkable
|
|
local tiles=v.tiles
|
|
|
|
if string.find(v.name,"fence") and tiles[1] then
|
|
inventory_image="mt2d_fence.png^" .. tiles[1] .. "^mt2d_fence.png^[makealpha:0,255,0"
|
|
tiles[1]=inventory_image
|
|
walkable=false
|
|
end
|
|
|
|
if #tiles==6 then
|
|
tiles={
|
|
tiles[1],
|
|
tiles[2],
|
|
tiles[3],
|
|
tiles[4],
|
|
tiles[6],
|
|
tiles[5],
|
|
}
|
|
if inventory_image=="" then
|
|
inventory_image=tiles[5]
|
|
end
|
|
end
|
|
if inventory_image=="" then
|
|
if tiles[1] and tiles[1].name and tiles[1].animation then
|
|
tiles = nil
|
|
elseif tiles[1] and type(tiles[1].name)=="string" then
|
|
inventory_image=tiles[1].name
|
|
|
|
elseif tiles[3] and type(tiles[3].name)=="string" then
|
|
inventory_image=tiles[3].name
|
|
|
|
if minetest.get_item_group(v.name,"soil") > 0 then
|
|
tiles={inventory_image}
|
|
end
|
|
elseif type(tiles[#tiles])=="string" then
|
|
inventory_image=tiles[#tiles]
|
|
end
|
|
end
|
|
|
|
minetest.override_item(i, {
|
|
tiles=tiles,
|
|
walkable=walkable,
|
|
inventory_image=inventory_image,
|
|
paramtype="light",
|
|
paramtype2="none",
|
|
drawtype="nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {{-0.5, -0.5, 0, 0.5, 0.5, 0}},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0}},
|
|
},
|
|
collision_box = {
|
|
type = "fixed",
|
|
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}},
|
|
},
|
|
})
|
|
end
|
|
end
|
|
if sethome then
|
|
sethome.go=function(name)
|
|
local pos=sethome.get(name)
|
|
if pos and mt2d.user[name] then
|
|
pos.z=0
|
|
pos.y=pos.y+1
|
|
mt2d.user[name].object:set_pos(pos)
|
|
mt2d.user[name].cam:set_pos(pos)
|
|
return true
|
|
elseif not pos then
|
|
return false
|
|
else
|
|
minetest.chat_send_player(name,"You can't go home in 3D mode")
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
mt2d.new_player=function(player)
|
|
local pos=player:get_pos()
|
|
pos={x=pos.x,y=pos.y,z=0}
|
|
for i=0,100,1 do
|
|
local n=minetest.registered_nodes[minetest.get_node({x=pos.x, y=pos.y+i, z=0}).name]
|
|
if n and not n.walkable then
|
|
pos.y=pos.y+i
|
|
break
|
|
end
|
|
end
|
|
player:set_pos(pos)
|
|
local id=math.random(1,9999)
|
|
local cam=minetest.add_entity({x=pos.x,y=pos.y,z=pos.z+5}, "mt2d:cam")
|
|
cam:get_luaentity().user=player
|
|
cam:get_luaentity().username=player:get_player_name()
|
|
cam:get_luaentity().id=id
|
|
mt2d.user[player:get_player_name()]={id=id,cam=cam,texture="character.png"}
|
|
player:set_attach(cam, "",{x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
|
player:hud_set_flags({wielditem=false})
|
|
player:set_nametag_attributes({color={a=0,r=255,g=255,b=255}})
|
|
player:set_properties({textures={"mt2d_air.png"}})
|
|
end
|
|
|
|
mt2d.to_3dplayer=function(player)
|
|
local name=player:get_player_name()
|
|
if mt2d.user3d[name] then
|
|
return
|
|
end
|
|
|
|
player:set_nametag_attributes({color={a=255,r=255,g=255,b=255}})
|
|
player:set_properties({textures={mt2d.user[name].texture}})
|
|
player:hud_set_flags({wielditem=true})
|
|
player:set_detach()
|
|
mt2d.user[name]=nil
|
|
mt2d.user3d[name]={timeout=false,player=player}
|
|
end
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
for name, a in pairs(mt2d.attach) do
|
|
if not (mt2d.user[name] or mt2d.user[name].id==a.id) or not (a.ob1:get_pos() and a.ob2:get_pos()) then
|
|
minetest.after(0, function(name)
|
|
mt2d.attach[name]=nil
|
|
end,name)
|
|
break
|
|
end
|
|
|
|
local pos1=a.ob1:get_pos()
|
|
local pos2=a.ob2:get_pos()
|
|
a.ob2:set_velocity({x=((pos1.x-pos2.x)+a.pos.x)*10,y=((pos1.y-pos2.y)+a.pos.y)*10,z=((pos1.z-pos2.z)+a.pos.z)*10})
|
|
|
|
|
|
local user
|
|
|
|
if a.ob1:get_luaentity() and a.ob1:get_luaentity().user then
|
|
user=a.ob1:get_luaentity().user
|
|
elseif a.ob2:get_luaentity() and a.ob2:get_luaentity().user then
|
|
user=a.ob2:get_luaentity().user
|
|
elseif a.ob1:is_player() then
|
|
user=a.ob1
|
|
elseif a.ob2:is_player() then
|
|
user=a.ob2
|
|
end
|
|
|
|
if user then
|
|
local yaw=user:get_look_yaw()
|
|
local pitch=user:get_look_pitch()
|
|
local tyaw=math.abs(yaw-4.71)
|
|
local tpitch=math.abs(pitch)
|
|
local npointable=not mt2d.pointable(pos2,user)
|
|
if tyaw>0.5 or (npointable and tyaw>0.2) then
|
|
user:set_look_yaw(3.14+((yaw-4.71)*0.99))
|
|
elseif tpitch>0.5 or (npointable and tpitch>0.2) then
|
|
user:set_look_pitch((pitch*0.99)*-1)
|
|
end
|
|
end
|
|
end
|
|
|
|
mt2d.timer=mt2d.timer+dtime
|
|
if mt2d.timer<2 then return end
|
|
mt2d.timer=0
|
|
for name, u in pairs(mt2d.user3d) do
|
|
if u.player:get_player_control().aux1 then
|
|
mt2d.new_player(u.player)
|
|
mt2d.user3d[name].timeout=true
|
|
minetest.after(2, function(name)
|
|
mt2d.user3d[name]=nil
|
|
end,name)
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
local pos=player:get_pos()
|
|
player:set_pos({x=pos.x,y=pos.y,z=0})
|
|
minetest.after(2, function(player)
|
|
mt2d.new_player(player)
|
|
end,player)
|
|
end)
|
|
|
|
minetest.register_on_respawnplayer(function(player)
|
|
minetest.after(0, function(player)
|
|
local pos=player:get_pos()
|
|
player:set_pos({x=pos.x,y=pos.y,z=5})
|
|
end,player)
|
|
minetest.after(1, function(player)
|
|
mt2d.new_player(player)
|
|
end,player)
|
|
end)
|
|
|
|
minetest.register_on_dieplayer(function(player)
|
|
player:set_detach()
|
|
minetest.after(0.1, function(player)
|
|
local bones_pos=minetest.find_node_near(player:get_pos(), 2, {"bones:bones"})
|
|
if bones_pos then
|
|
local bones=minetest.get_node(bones_pos)
|
|
local name=player:get_player_name()
|
|
for i, replace_pos in pairs(mt2d.get_nodes_radius(bones_pos,15)) do
|
|
local replace=minetest.get_node(replace_pos).name
|
|
if (minetest.registered_nodes[replace] and minetest.registered_nodes[replace].buildable_to) then
|
|
minetest.set_node(replace_pos,bones)
|
|
minetest.get_meta(replace_pos):from_table(minetest.get_meta(bones_pos):to_table())
|
|
minetest.set_node(bones_pos,{name="air"})
|
|
return
|
|
end
|
|
end
|
|
local replace_pos={x=bones_pos.x,y=bones_pos.y,z=0}
|
|
local replace=minetest.get_node(replace_pos).name
|
|
|
|
if minetest.is_protected(replace_pos, name)==false and
|
|
(minetest.get_item_group(replace,"stone")>0
|
|
or minetest.get_item_group(replace,"soil")>0
|
|
or minetest.get_item_group(replace,"sand")>0) then
|
|
minetest.set_node(replace_pos,bones)
|
|
minetest.get_meta(replace_pos):from_table(minetest.get_meta(bones_pos):to_table())
|
|
minetest.get_meta(replace_pos):get_inventory():add_item("main",{name=replace})
|
|
minetest.set_node(bones_pos,{name="air"})
|
|
return
|
|
end
|
|
|
|
end
|
|
end,player)
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
player:set_detach()
|
|
mt2d.user[player:get_player_name()]=nil
|
|
mt2d.user3d[player:get_player_name()]=nil
|
|
end)
|
|
|
|
mt2d.pointable=function(p1,user)
|
|
local dir=user:get_look_dir()
|
|
local p2=user:get_pos()
|
|
p2={x=p2.x+(dir.x*5),y=p2.y+1.6+(dir.y*5),z=p2.z+(dir.z*5)}
|
|
p1.y=p1.y+0.6
|
|
local v = {x = p1.x - p2.x, y = p1.y - p2.y, z = p1.z - p2.z}
|
|
local amount = (v.x ^ 2 + v.y ^ 2 + v.z ^ 2) ^ 0.5
|
|
local d=math.sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z))
|
|
v.x = (v.x / amount)*-1
|
|
v.y = (v.y / amount)*-1
|
|
v.z = (v.z / amount)*-1
|
|
local hit
|
|
for i=1,d,0.5 do
|
|
local node=minetest.get_node({x=p1.x+(v.x*i),y=p1.y+(v.y*i),z=p1.z+(v.z*i)})
|
|
if hit and minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].walkable then
|
|
return false
|
|
end
|
|
hit=true
|
|
end
|
|
return true
|
|
end
|
|
|
|
mt2d.player_anim=function(self,typ)
|
|
if typ==self.anim then
|
|
return
|
|
end
|
|
self.anim=typ
|
|
self.ob:set_animation({x=mt2d.playeranim[typ].x, y=mt2d.playeranim[typ].y, },mt2d.playeranim[typ].speed,0)
|
|
|
|
if self.user and self.user:get_wielded_item()~=self.wielditem then
|
|
self.wielditem=self.user:get_wielded_item():get_name()
|
|
local t="mt2d_air.png"
|
|
|
|
local def1=minetest.registered_items[self.wielditem]
|
|
|
|
if def1 and def1.inventory_image and def1.inventory_image~="" then
|
|
t=def1.inventory_image
|
|
elseif def1 and def1.tiles and type(def1.tiles[1])=="string" then
|
|
t=def1.tiles[1]
|
|
end
|
|
self.ob:set_properties({textures={t,mt2d.user[self.username].texture}})
|
|
end
|
|
return self
|
|
end
|
|
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
local air=minetest.get_content_id("air")
|
|
local blocking=minetest.get_content_id("mt2d:blocking")
|
|
local sky=minetest.get_content_id("mt2d:blocking_sky")
|
|
local stone=minetest.get_content_id("mt2d:blocking_stone")
|
|
local vox = minetest.get_voxel_manip()
|
|
local min, max = vox:read_from_map(minp, maxp)
|
|
local area = VoxelArea:new({MinEdge = min, MaxEdge = max})
|
|
local data = vox:get_data()
|
|
for z = minp.z, maxp.z do
|
|
for y = minp.y, maxp.y do
|
|
for x = minp.x, maxp.x do
|
|
if z==-1 and y>0 then
|
|
data[area:index(x,y,z)]=sky
|
|
elseif z==-1 and y<1 then
|
|
data[area:index(x,y,z)]=stone
|
|
elseif z==1 or z==5 then
|
|
data[area:index(x,y,z)]=blocking
|
|
elseif z~=0 then
|
|
data[area:index(x,y,z)]=air
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|
|
vox:set_data(data)
|
|
vox:write_to_map()
|
|
vox:update_map()
|
|
vox:update_liquids()
|
|
end)
|
|
|
|
mt2d.punch=function(ob1,ob2,hp)
|
|
if not (ob1 and ob2) then
|
|
return
|
|
end
|
|
hp=hp or 1
|
|
if ob1:is_player() then
|
|
ob1:set_hp(ob1:get_hp()-hp)
|
|
else
|
|
ob1:punch(ob2,1,{full_punch_interval=1,damage_groups={fleshy=hp}})
|
|
end
|
|
end
|
|
|
|
minetest.spawn_item=function(pos, item)
|
|
local e=minetest.add_entity(pos, "__builtin:item")
|
|
if e then
|
|
e:get_luaentity():set_item(ItemStack(item):to_string())
|
|
minetest.after(0, function(e)
|
|
local self=e:get_luaentity()
|
|
if self and self.dropped_by and mt2d.user[self.dropped_by] then
|
|
local ob=mt2d.user[self.dropped_by].object
|
|
local yaw=math.floor(ob:get_yaw()*10)*0.1
|
|
local v={x=0,y=0,z=0}
|
|
local p=ob:get_pos()
|
|
|
|
if yaw==4.7 then
|
|
v.x=2
|
|
elseif yaw==1.5 then
|
|
v.x=-2
|
|
else
|
|
v.x=0
|
|
end
|
|
|
|
e:set_pos({x=pos.x+(v.x/2),y=pos.y-0.5,z=0})
|
|
e:set_velocity({x=v.x,y=0,z=0})
|
|
|
|
end
|
|
end,e)
|
|
|
|
minetest.after(10, function(e)
|
|
if e and e:get_luaentity() then
|
|
local node=minetest.registered_nodes[minetest.get_node(e:get_pos()).name]
|
|
if node and node.damage_per_second>0 then
|
|
e:remove()
|
|
end
|
|
end
|
|
end,e)
|
|
end
|
|
return e
|
|
end
|
|
|
|
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
|
local ppos=placer:get_pos()
|
|
|
|
if pos.x==math.floor(ppos.x+0.5) and (pos.y==math.floor(ppos.y) or pos.y==math.floor(ppos.y+1)) then
|
|
minetest.set_node(pos,oldnode)
|
|
return true
|
|
end
|
|
for x=-1,1,1 do
|
|
for y=-1,1,1 do
|
|
if x+y~=0 and minetest.get_node({x=pos.x+x,y=pos.y+y,z=0}).name~="air" then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
minetest.set_node(pos,oldnode)
|
|
return true
|
|
end)
|
|
|
|
mt2d.get_nodes_radius=function(pos,rad)
|
|
rad=rad or 2
|
|
local nodes={}
|
|
local p
|
|
for r=0,rad,1.5 do
|
|
for a=-r,r,0.5 do
|
|
p={ x=pos.x+(math.cos(a)*r)*0.5,
|
|
y=pos.y+(math.sin(a)*r)*0.5,
|
|
z=0
|
|
}
|
|
nodes[minetest.pos_to_string(p)]=p
|
|
end
|
|
end
|
|
return nodes
|
|
end
|
|
|
|
mt2d.set_attach=function(name,object,object_to_attach,pos)
|
|
pos=pos or {}
|
|
pos={x=pos.x or 0,y=pos.y or 0,z=pos.z or 0}
|
|
mt2d.attach[name]={
|
|
name=name,
|
|
id=mt2d.user[name].id,
|
|
ob1=object,
|
|
ob2=object_to_attach,
|
|
pos=pos or {x=0,y=0,z=0}
|
|
}
|
|
end
|
|
|
|
mt2d.get_attach=function(name)
|
|
return mt2d.attach[name]
|
|
end
|
|
|
|
mt2d.set_detach=function(name)
|
|
if mt2d.attach[name] then
|
|
mt2d.attach[name]=nil
|
|
end
|
|
end
|
|
|
|
mt2d.path_iremove=function(path,index)
|
|
path[minetest.pos_to_string(path[index])]=nil
|
|
table.remove(path,index)
|
|
return path
|
|
end
|
|
|
|
mt2d.path=function(pos,l,dir,group)
|
|
local c={}
|
|
local lastpos={x=math.floor(pos.x),y=math.floor(pos.y),z=0}
|
|
for i=dir,l*dir,dir do
|
|
c,lastpos=mt2d.path_add(dir,c,lastpos,group)
|
|
if not lastpos then
|
|
break
|
|
end
|
|
end
|
|
return c
|
|
end
|
|
|
|
mt2d.path_add=function(d,c,lp,group)
|
|
for i, r in pairs({{x=0,y=0},{x=d,y=0},{x=0,y=1},{x=0,y=-1},{x=-d,y=0}}) do
|
|
local p={x=lp.x+r.x,y=lp.y+r.y,z=0}
|
|
local ps=minetest.pos_to_string(p)
|
|
if not c[ps] and minetest.get_item_group(minetest.get_node(p).name,group)>0 then
|
|
c[ps]=p
|
|
table.insert(c,p)
|
|
return c,p
|
|
end
|
|
end
|
|
return c
|
|
end
|