added support for mirrored and rotated build
This commit is contained in:
parent
30db22827c
commit
edcb6a38d9
@ -67,6 +67,8 @@ License: LGPLv2
|
||||
- plan_obj.data.groundnode_count - count of nodes found for ground_y determination (internal)
|
||||
- plan_obj.data.min_pos - minimal {x,y,z} vector
|
||||
- plan_obj.data.max_pos - maximal {x,y,z} vector
|
||||
- plan_obj.facedir - Plan rotation - x+ axis supported only (values 0-3)
|
||||
- plan_obj.mirrored - (bool) Mirrored build - mirror to z-axis. Note: if you need x-axis mirror - just rotate the building by 2 in addition
|
||||
|
||||
## Node object
|
||||
### class-methods
|
||||
@ -83,6 +85,7 @@ License: LGPLv2
|
||||
- node_obj:remove_from_plan() - remove this node from plan
|
||||
- node_obj:get_under() - returns the node under this one if exists in plan
|
||||
- node_obj:get_above() - returns the node above this one if exists in plan
|
||||
- node_obj:rotate_facedir(facedir) - rotate the node - is internally used for plan rotation in get_mapped() - supported 0-3 (x+ axis) only
|
||||
|
||||
### object-attributes
|
||||
- node_obj.name - original node name without mapping
|
||||
|
224
mapping.lua
224
mapping.lua
@ -8,114 +8,144 @@ local mapping = {}
|
||||
mapping.c_free_item = "default:cloud"
|
||||
|
||||
-----------------------------------------------
|
||||
-- door compatibility. Seems the old doors was facedir and now the wallmounted values should be used
|
||||
-- door compatibility. Seems the old doors was facedir and now the wallmounted values should be used (custom_function)
|
||||
-----------------------------------------------
|
||||
local function __param2_wallmounted_to_facedir(nodeinfo, pos, wpos)
|
||||
if nodeinfo.param2 == 0 then -- +y?
|
||||
nodeinfo.param2 = 0
|
||||
elseif nodeinfo.param2 == 1 then -- -y?
|
||||
nodeinfo.param2 = 1
|
||||
elseif nodeinfo.param2 == 2 then --unsure
|
||||
nodeinfo.param2 = 3
|
||||
elseif nodeinfo.param2 == 3 then --unsure
|
||||
nodeinfo.param2 = 1
|
||||
elseif nodeinfo.param2 == 4 then --unsure
|
||||
nodeinfo.param2 = 2
|
||||
elseif nodeinfo.param2 == 5 then --unsure
|
||||
nodeinfo.param2 = 0
|
||||
local function __param2_wallmounted_to_facedir(mapped, node)
|
||||
if mapped.param2 == 0 then -- +y?
|
||||
mapped.param2 = 0
|
||||
elseif mapped.param2 == 1 then -- -y?
|
||||
mapped.param2 = 1
|
||||
elseif mapped.param2 == 2 then --unsure
|
||||
mapped.param2 = 3
|
||||
elseif mapped.param2 == 3 then --unsure
|
||||
mapped.param2 = 1
|
||||
elseif mapped.param2 == 4 then --unsure
|
||||
mapped.param2 = 2
|
||||
elseif mapped.param2 == 5 then --unsure
|
||||
mapped.param2 = 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function __torches_compat(nodeinfo, pos, wpos)
|
||||
|
||||
-----------------------------------------------
|
||||
-- Torches compatibility (custom_function)
|
||||
-----------------------------------------------
|
||||
local function __torches_compat(mapped, node)
|
||||
-- from default:3dtorch-lbm
|
||||
if nodeinfo.param2 == 0 then
|
||||
nodeinfo.name = "default:torch_ceiling"
|
||||
elseif nodeinfo.param2 == 1 then
|
||||
nodeinfo.name = "default:torch"
|
||||
if mapped.param2 == 0 then
|
||||
mapped.name = "default:torch_ceiling"
|
||||
elseif mapped.param2 == 1 then
|
||||
mapped.name = "default:torch"
|
||||
else
|
||||
nodeinfo.name = "default:torch_wall"
|
||||
mapped.name = "default:torch_wall"
|
||||
end
|
||||
end
|
||||
|
||||
local u = {}
|
||||
local unknown_nodes_data = u
|
||||
-- Fallback nodes replacement of unknown nodes
|
||||
-- Maybe it is beter to use aliases for unknown notes. But anyway
|
||||
u["xpanes:pane_glass_10"] = { name = "xpanes:pane_10" }
|
||||
u["xpanes:pane_glass_5"] = { name = "xpanes:pane_5" }
|
||||
u["beds:bed_top_blue"] = { name = "beds:bed_top" }
|
||||
u["beds:bed_bottom_blue"] = { name = "beds:bed_bottom" }
|
||||
|
||||
u["homedecor:table_lamp_max"] = { name = "homedecor:table_lamp_white_max" }
|
||||
u["homedecor:refrigerator"] = { name = "homedecor:refrigerator_steel" }
|
||||
-----------------------------------------------
|
||||
-- Unknown nodes mapping
|
||||
-----------------------------------------------
|
||||
local unknown_nodes_data = {
|
||||
-- Fallback / Compatibility nodes replacement for ingame unknown nodes
|
||||
["xpanes:pane_glass_10"] = { name = "xpanes:pane_10" },
|
||||
["xpanes:pane_glass_5"] = { name = "xpanes:pane_5" },
|
||||
["beds:bed_top_blue"] = { name = "beds:bed_top" },
|
||||
["beds:bed_bottom_blue"] = { name = "beds:bed_bottom" },
|
||||
|
||||
u["ethereal:green_dirt"] = { name = "default:dirt_with_grass" }
|
||||
["homedecor:table_lamp_max"] = { name = "homedecor:table_lamp_white_max" },
|
||||
["homedecor:refrigerator"] = { name = "homedecor:refrigerator_steel" },
|
||||
|
||||
u["doors:door_wood_b_c"] = {name = "doors:door_wood_a", {["meta"] = {["fields"] = {["state"] = "1"}}}, custom_function = __param2_wallmounted_to_facedir } --closed
|
||||
u["doors:door_wood_b_o"] = {name = "doors:door_wood_b", {["meta"] = {["fields"] = {["state"] = "3"}}}, custom_function = __param2_wallmounted_to_facedir } --open
|
||||
u["doors:door_wood_b_1"] = {name = "doors:door_wood_a", {["meta"] = {["fields"] = {["state"] = "0"}}}} --Left door closed
|
||||
u["doors:door_wood_b_2"] = {name = "doors:door_wood_b", {["meta"] = {["fields"] = {["state"] = "2"}}}} --right door closed
|
||||
u["doors:door_wood_a_c"] = {name = "doors:hidden" }
|
||||
u["doors:door_wood_a_o"] = {name = "doors:hidden" }
|
||||
u["doors:door_wood_t_1"] = {name = "doors:hidden" }
|
||||
u["doors:door_wood_t_2"] = {name = "doors:hidden" }
|
||||
["ethereal:green_dirt"] = { name = "default:dirt_with_grass" },
|
||||
|
||||
u["doors:door_glass_b_c"] = {name = "doors:door_glass_a", {["meta"] = {["fields"] = {["state"] = "1"}}}, custom_function = __param2_wallmounted_to_facedir } --closed
|
||||
u["doors:door_glass_b_o"] = {name = "doors:door_glass_b", {["meta"] = {["fields"] = {["state"] = "3"}}}, custom_function = __param2_wallmounted_to_facedir } --open
|
||||
u["doors:door_glass_b_1"] = {name = "doors:door_glass_a", {["meta"] = {["fields"] = {["state"] = "0"}}}} --Left door closed
|
||||
u["doors:door_glass_b_2"] = {name = "doors:door_glass_b", {["meta"] = {["fields"] = {["state"] = "2"}}}} --right door closed
|
||||
u["doors:door_glass_a_c"] = {name = "doors:hidden" }
|
||||
u["doors:door_glass_a_o"] = {name = "doors:hidden" }
|
||||
u["doors:door_glass_t_1"] = {name = "doors:hidden" }
|
||||
u["doors:door_glass_t_2"] = {name = "doors:hidden" }
|
||||
["doors:door_wood_b_c"] = {name = "doors:door_wood_a", meta = {fields = {state = 1}}, custom_function = __param2_wallmounted_to_facedir }, --closed
|
||||
["doors:door_wood_b_o"] = {name = "doors:door_wood_b", meta = {fields = {state = 3}}, custom_function = __param2_wallmounted_to_facedir }, --open
|
||||
["doors:door_wood_b_1"] = {name = "doors:door_wood_a", meta = {fields = {state = 0}}}, --Left door closed
|
||||
["doors:door_wood_b_2"] = {name = "doors:door_wood_b", meta = {fields = {state = 2}}}, --right door closed
|
||||
["doors:door_wood_a_c"] = {name = "doors:hidden" },
|
||||
["doors:door_wood_a_o"] = {name = "doors:hidden" },
|
||||
["doors:door_wood_t_1"] = {name = "doors:hidden" },
|
||||
["doors:door_wood_t_2"] = {name = "doors:hidden" },
|
||||
|
||||
u["doors:door_steel_b_c"] = {name = "doors:door_steel_a", {["meta"] = {["fields"] = {["state"] = "1"}}}, custom_function = __param2_wallmounted_to_facedir } --closed
|
||||
u["doors:door_steel_b_o"] = {name = "doors:door_steel_b", {["meta"] = {["fields"] = {["state"] = "3"}}}, custom_function = __param2_wallmounted_to_facedir } --open
|
||||
u["doors:door_steel_b_1"] = {name = "doors:door_steel_a", {["meta"] = {["fields"] = {["state"] = "0"}}}} --Left door closed
|
||||
u["doors:door_steel_b_2"] = {name = "doors:door_steel_b", {["meta"] = {["fields"] = {["state"] = "2"}}}} --right door closed
|
||||
u["doors:door_steel_a_c"] = {name = "doors:hidden" }
|
||||
u["doors:door_steel_a_o"] = {name = "doors:hidden" }
|
||||
u["doors:door_steel_t_1"] = {name = "doors:hidden" }
|
||||
u["doors:door_steel_t_2"] = {name = "doors:hidden" }
|
||||
["doors:door_glass_b_c"] = {name = "doors:door_glass_a", meta = {fields = {state = 1}}, custom_function = __param2_wallmounted_to_facedir }, --closed
|
||||
["doors:door_glass_b_o"] = {name = "doors:door_glass_b", meta = {fields = {state = 3}}, custom_function = __param2_wallmounted_to_facedir }, --open
|
||||
["doors:door_glass_b_1"] = {name = "doors:door_glass_a", meta = {fields = {state = 0}}}, --Left door closed
|
||||
["doors:door_glass_b_2"] = {name = "doors:door_glass_b", meta = {fields = {state = 2}}}, --right door closed
|
||||
["doors:door_glass_a_c"] = {name = "doors:hidden" },
|
||||
["doors:door_glass_a_o"] = {name = "doors:hidden" },
|
||||
["doors:door_glass_t_1"] = {name = "doors:hidden" },
|
||||
["doors:door_glass_t_2"] = {name = "doors:hidden" },
|
||||
|
||||
u["fallback"] = {name = "air" }
|
||||
["doors:door_steel_b_c"] = {name = "doors:door_steel_a", meta = {fields = {state = 1}}, custom_function = __param2_wallmounted_to_facedir }, --closed
|
||||
["doors:door_steel_b_o"] = {name = "doors:door_steel_b", meta = {fields = {state = 3}}, custom_function = __param2_wallmounted_to_facedir }, --open
|
||||
["doors:door_steel_b_1"] = {name = "doors:door_steel_a", meta = {fields = {state = 0}}}, --Left door closed
|
||||
["doors:door_steel_b_2"] = {name = "doors:door_steel_b", meta = {fields = {state = 2}}}, --right door closed
|
||||
["doors:door_steel_a_c"] = {name = "doors:hidden" },
|
||||
["doors:door_steel_a_o"] = {name = "doors:hidden" },
|
||||
["doors:door_steel_t_1"] = {name = "doors:hidden" },
|
||||
["doors:door_steel_t_2"] = {name = "doors:hidden" },
|
||||
|
||||
local c = {}
|
||||
local default_replacements = c
|
||||
["fallback"] = {name = "air" },
|
||||
}
|
||||
|
||||
-----------------------------------------------
|
||||
-- Default Replacements and adjustments
|
||||
-----------------------------------------------
|
||||
local default_replacements = {
|
||||
-- "name" and "cost_item" are optional.
|
||||
-- if name is missed it will not be changed
|
||||
-- if cost_item is missed it will be determinated as usual (from changed name)
|
||||
-- if cost_item is missed it will be determinated as usual (name or drop)
|
||||
-- a crazy sample is: instead of cobble place goldblock, use wood as payment
|
||||
-- c["default:cobble"] = { name = "default:goldblock", cost_item = "default:wood" }
|
||||
|
||||
c["beds:bed_top"] = { cost_item = mapping.c_free_item } -- the bottom of the bed is payed, so buld the top for free
|
||||
["beds:bed_top"] = { cost_item = mapping.c_free_item }, -- the bottom of the bed is payed, so buld the top for free
|
||||
|
||||
-- it is hard to get a source in survival, so we use buckets. Note, the bucket is lost after usage by NPC
|
||||
c["default:lava_source"] = { cost_item = "bucket:bucket_lava" }
|
||||
c["default:river_water_source"] = { cost_item = "bucket:bucket_river_water" }
|
||||
c["default:water_source"] = { cost_item = "bucket:bucket_water" }
|
||||
-- it is hard to get a source in survival, so we use buckets. Note, the bucket is lost after usage by NPC
|
||||
["default:lava_source"] = { cost_item = "bucket:bucket_lava" },
|
||||
["default:river_water_source"] = { cost_item = "bucket:bucket_river_water" },
|
||||
["default:water_source"] = { cost_item = "bucket:bucket_water" },
|
||||
|
||||
-- does not sense to set flowing water because it flow away without the source (and will be generated trough source)
|
||||
c["default:water_flowing"] = { name = "air" }
|
||||
c["default:lava_flowing"] = { name = "air" }
|
||||
c["default:river_water_flowing"] = { name = "air" }
|
||||
-- does not sense to set flowing water because it flow away without the source (and will be generated trough source)
|
||||
["default:water_flowing"] = { name = "air" },
|
||||
["default:lava_flowing"] = { name = "air" },
|
||||
["default:river_water_flowing"] = { name = "air" },
|
||||
|
||||
-- pay different dirt types by the sane dirt
|
||||
c["default:dirt_with_dry_grass"] = { cost_item = "default:dirt" }
|
||||
c["default:dirt_with_grass"] = { cost_item = "default:dirt" }
|
||||
c["default:dirt_with_snow"] = { cost_item = "default:dirt" }
|
||||
-- pay different dirt types by the sane dirt
|
||||
["default:dirt_with_dry_grass"] = { cost_item = "default:dirt" },
|
||||
["default:dirt_with_grass"] = { cost_item = "default:dirt" },
|
||||
["default:dirt_with_snow"] = { cost_item = "default:dirt" },
|
||||
|
||||
-- Changed with MTG-0.4.16
|
||||
c["xpanes:pane_5"] = { name = "xpanes:pane_flat", param2 = 0 } --unsure
|
||||
c["xpanes:pane_10"] = { name = "xpanes:pane_flat", param2 = 1 } --unsure
|
||||
-- Changed with MTG-0.4.16
|
||||
["xpanes:pane_5"] = { name = "xpanes:pane_flat", param2 = 0 }, --unsure
|
||||
["xpanes:pane_10"] = { name = "xpanes:pane_flat", param2 = 1 }, --unsure
|
||||
|
||||
c["default:torch"] = { custom_function = __torches_compat }
|
||||
c["torches:wall"] = { name = "default:torch_wall" }
|
||||
["default:torch"] = { custom_function = __torches_compat },
|
||||
["torches:wall"] = { name = "default:torch_wall" },
|
||||
}
|
||||
|
||||
-----------------------------------------------
|
||||
-- copy table of mapping entry
|
||||
-- Handle doors mirroring (_a vs _b)
|
||||
-----------------------------------------------
|
||||
function __mirror_doors(mr)
|
||||
if not mr.node_def.door then
|
||||
return
|
||||
end
|
||||
local node_name = mr.name
|
||||
if node_name:sub(-1) == 'a' then
|
||||
node_name = node_name:sub(1,-2)..'b'
|
||||
else
|
||||
node_name = node_name:sub(1,-2)..'a'
|
||||
end
|
||||
if minetest.registered_nodes[node_name] then
|
||||
mr.node_def = minetest.registered_nodes[node_name]
|
||||
mr.name = node_name
|
||||
if mr.meta and mr.meta.fields and mr.meta.fields.state then
|
||||
mr.meta.fields.state = (mr.meta.fields.state + 2) % 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- merge entry
|
||||
-----------------------------------------------
|
||||
local function merge_map_entry(entry1, entry2)
|
||||
if entry2 then
|
||||
@ -164,12 +194,11 @@ end
|
||||
-----------------------------------------------
|
||||
function mapping.map_unknown(name)
|
||||
local map = unknown_nodes_data[name]
|
||||
if not map or map.name == name then -- no fallback mapping. don't use the node
|
||||
if not map or map.name == name or not minetest.registered_nodes[map.name] then
|
||||
dprint("mapping failed:", name, dump(map))
|
||||
print("unknown nodes in building", name)
|
||||
return unknown_nodes_data["fallback"]
|
||||
end
|
||||
|
||||
dprint("mapped", name, "to", map.name)
|
||||
return merge_map_entry(map)
|
||||
end
|
||||
@ -177,35 +206,20 @@ end
|
||||
-----------------------------------------------
|
||||
-- Take filters and actions on nodes before building
|
||||
-----------------------------------------------
|
||||
function mapping.map(name)
|
||||
function mapping.map(name, plan)
|
||||
-- get mapped registred node name for further mappings
|
||||
local mr = {name = name}
|
||||
local node_chk = minetest.registered_nodes[name]
|
||||
|
||||
--do fallback mapping if not registred node
|
||||
if not node_chk then
|
||||
local fallback = mapping.map_unknown(name)
|
||||
if fallback then
|
||||
dprint("map fallback:", dump(fallback))
|
||||
local fbmapped = mapping.map(fallback.name)
|
||||
if fbmapped then
|
||||
return merge_map_entry(fbmapped, fallback) --merge fallback values into the mapped node
|
||||
end
|
||||
end
|
||||
dprint("unmapped node", name)
|
||||
return
|
||||
mr = merge_map_entry(mapping.map_unknown(name), mr)
|
||||
end
|
||||
|
||||
-- get default replacement
|
||||
local map = default_replacements[name]
|
||||
local mr -- mapped return table
|
||||
if not map then
|
||||
mr = {}
|
||||
mr.name = name
|
||||
else
|
||||
mr = merge_map_entry(map)
|
||||
if mr.name == nil then
|
||||
mr.name = name
|
||||
end
|
||||
if map then
|
||||
mr = merge_map_entry(map, mr)
|
||||
end
|
||||
|
||||
--disabled by mapping
|
||||
@ -215,6 +229,11 @@ function mapping.map(name)
|
||||
|
||||
local node_def = minetest.registered_nodes[mr.name]
|
||||
mr.node_def = node_def
|
||||
|
||||
if plan and plan.mirrored then
|
||||
__mirror_doors(mr)
|
||||
end
|
||||
|
||||
-- determine cost_item
|
||||
if not mr.cost_item then
|
||||
--Check for price or if it is free
|
||||
@ -246,6 +265,7 @@ end
|
||||
|
||||
------------------------------------------
|
||||
-- Cache some node content ID
|
||||
------------------------------------------
|
||||
mapping._protected_content_ids = {} -- this nodes detects other buildings
|
||||
mapping._over_surface_content_ids = {} -- this nodes detects surface
|
||||
mapping._volatile_contend_ids = {} -- this nodes will not be removed before placing new one
|
||||
|
124
node.lua
124
node.lua
@ -43,6 +43,32 @@ function node_class:get_world_pos()
|
||||
return self._world_pos
|
||||
end
|
||||
|
||||
-------------------------------------
|
||||
-- Handle rotation
|
||||
--------------------------------------
|
||||
function node_class:rotate_facedir(facedir)
|
||||
-- rotate wallmounted
|
||||
local mapped = self.mapped
|
||||
if mapped.node_def.paramtype2 == "wallmounted" then
|
||||
local param2_dir = mapped.param2 % 8
|
||||
local param2_color = mapped.param2 - param2_dir
|
||||
if self.plan.mirrored then
|
||||
param2_dir = node.rotation_wallmounted_mirrored_map[param2_dir]
|
||||
end
|
||||
mapped.param2 = node.rotation_wallmounted_map[facedir][param2_dir] + param2_color
|
||||
elseif mapped.node_def.paramtype2 == "facedir" then
|
||||
-- rotate facedir
|
||||
local param2_dir = mapped.param2 % 32
|
||||
local param2_color = mapped.param2 - param2_dir
|
||||
if self.plan.mirrored then
|
||||
param2_dir = node.rotation_facedir_mirrored_map[param2_dir]
|
||||
end
|
||||
mapped.param2 = node.rotation_facedir_map[facedir][param2_dir] + param2_color
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------
|
||||
-- Get all information to build the node
|
||||
--------------------------------------
|
||||
@ -53,7 +79,7 @@ function node_class:get_mapped()
|
||||
|
||||
local mappedinfo = self.nodeinfo.mapped
|
||||
if not mappedinfo then
|
||||
mappedinfo = mapping.map(self.name)
|
||||
mappedinfo = mapping.map(self.name, self.plan)
|
||||
self.nodeinfo.mapped = mappedinfo
|
||||
self.mapped = nil
|
||||
end
|
||||
@ -75,13 +101,15 @@ function node_class:get_mapped()
|
||||
mapped.prob = mapped.prob or self.data.prob
|
||||
|
||||
if mapped.custom_function ~= nil then
|
||||
mapped.custom_function(mapped, self._plan_pos, self:get_world_pos())
|
||||
mapped.custom_function(mapped, self)
|
||||
mapped.custom_function = nil
|
||||
end
|
||||
|
||||
mapped.content_id = minetest.get_content_id(mapped.name)
|
||||
self.mapped = mapped
|
||||
self.cost_item = mapped.cost_item -- workaround / backwards compatibility to npcf_builder
|
||||
|
||||
self:rotate_facedir(self.plan.facedir)
|
||||
return mapped
|
||||
end
|
||||
|
||||
@ -125,5 +153,97 @@ function node_class:remove_from_plan()
|
||||
self.plan:del_node(self._plan_pos)
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------
|
||||
-- Precalculated rotation mapping
|
||||
--------------------------------------
|
||||
node.rotation_wallmounted_map = {
|
||||
[0] = {1,2,3,4,5,[0] = 0},
|
||||
[1] = {1,5,4,2,3,[0] = 0},
|
||||
[2] = {1,3,2,5,4,[0] = 0},
|
||||
[3] = {1,4,5,3,2,[0] = 0},
|
||||
}
|
||||
node.rotation_wallmounted_mirrored_map = {1,3,2,4,5,[0] = 0}
|
||||
|
||||
node.rotation_facedir_map = {
|
||||
[0] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,[0] = 0},
|
||||
[1] = { 2, 3, 0,13,14,15,12,17,18,19,16, 9,10,11, 8, 5, 6, 7, 4,23,20,21,22,[0] = 1},
|
||||
[2] = { 3, 0, 1,10,11, 8, 9, 6, 7, 4, 5,18,19,16,17,14,15,12,13,22,23,20,21,[0] = 2},
|
||||
[3] = { 0, 1, 2,19,16,17,18,15,12,13,14, 7, 4, 5, 6,11, 8, 9,10,21,22,23,20,[0] = 3},
|
||||
}
|
||||
node.rotation_facedir_mirrored_map = {3, 2, 1, 4, 7, 6, 5, 8, 11,10,9,16,19,18,17,12,15,14,13,20,23,22,21,[0] = 0}
|
||||
|
||||
--[[
|
||||
--- Temporary code to calculate the wallmounted map
|
||||
node.rotation_wallmounted_map = {}
|
||||
for rotate = 0, 3 do -- facedir
|
||||
node.rotation_wallmounted_cache[rotate] = {}
|
||||
for wallmounted = 0, 5 do
|
||||
local facedir, new_wallmounted
|
||||
if wallmounted > 1 then
|
||||
if wallmounted == 2 then
|
||||
facedir = 1
|
||||
elseif wallmounted == 3 then
|
||||
facedir = 3
|
||||
elseif wallmounted == 4 then
|
||||
facedir = 0
|
||||
elseif wallmounted == 5 then
|
||||
facedir = 2
|
||||
end
|
||||
facedir = (facedir + rotate) % 4 --rotate
|
||||
if facedir == 1 then
|
||||
new_wallmounted = 2
|
||||
elseif facedir == 3 then
|
||||
new_wallmounted = 3
|
||||
elseif facedir == 0 then
|
||||
new_wallmounted = 4
|
||||
elseif facedir == 2 then
|
||||
new_wallmounted = 5
|
||||
end
|
||||
else
|
||||
new_wallmounted = wallmounted
|
||||
end
|
||||
node.rotation_wallmounted_cache[rotate][wallmounted] = new_wallmounted
|
||||
end
|
||||
end
|
||||
print(dump(node.rotation_wallmounted_cache))
|
||||
]]
|
||||
|
||||
--[[
|
||||
local direction_map = {1, 3, 2, 4}
|
||||
local direction_map_mirror = {1, 4, 2, 3}
|
||||
|
||||
for rotate = 0, 3 do
|
||||
node.rotation_facedir_map[rotate] = {}
|
||||
for wal_direction = 0, 5 do
|
||||
for wal_rotate = 0, 3 do
|
||||
local oldwal = wal_direction*4+wal_rotate
|
||||
if wal_direction == 0 then -- y+
|
||||
new_wal_direction = 0
|
||||
new_wal_rotate = (wal_rotate + rotate) % 4
|
||||
elseif wal_direction == 5 then -- y-
|
||||
new_wal_direction = 5
|
||||
new_wal_rotate = (4+wal_rotate - rotate) % 4
|
||||
else
|
||||
new_wal_direction = direction_map[(direction_map[wal_direction] + rotate-1)%4+1]
|
||||
new_wal_rotate = (wal_rotate + rotate) % 4
|
||||
if rotate == 0 then
|
||||
local new_wal_rotate_mirror = new_wal_rotate
|
||||
if new_wal_rotate_mirror == 1 then
|
||||
new_wal_rotate_mirror = 3
|
||||
elseif new_wal_rotate_mirror == 3 then
|
||||
new_wal_rotate_mirror = 1
|
||||
end
|
||||
local new_wal_direction_mirror = direction_map_mirror[(direction_map[wal_direction] + rotate-1)%4+1]
|
||||
print(rotate, oldwal, (new_wal_direction_mirror*4+new_wal_rotate_mirror))
|
||||
end
|
||||
end
|
||||
node.rotation_facedir_map[rotate][oldwal] = new_wal_direction*4 + new_wal_rotate
|
||||
end
|
||||
end
|
||||
end
|
||||
print(dump(node.rotation_facedir_map))
|
||||
-- ]]
|
||||
|
||||
-------------------
|
||||
return node
|
||||
|
90
plan.lua
90
plan.lua
@ -26,14 +26,17 @@ function plan.new(plan_id , anchor_pos)
|
||||
self.__index = plan_class
|
||||
self.plan_id = plan_id
|
||||
self.anchor_pos = anchor_pos
|
||||
self.data = {}
|
||||
self.data.min_pos = {}
|
||||
self.data.max_pos = {}
|
||||
self.data.groundnode_count = 0
|
||||
self.data.ground_y = -1 --if nothing defined, it is under the building
|
||||
self.data.scm_data_cache = {}
|
||||
self.data.nodeinfos = {}
|
||||
self.data.nodecount = 0
|
||||
self.facedir = 0
|
||||
self.mirrored = false
|
||||
self.data = {
|
||||
min_pos = {},
|
||||
max_pos = {},
|
||||
groundnode_count = 0,
|
||||
ground_y = -1, --if nothing defined, it is under the building
|
||||
scm_data_cache = {},
|
||||
nodeinfos = {},
|
||||
nodecount = 0,
|
||||
}
|
||||
self.status = "new"
|
||||
return self -- the plan object
|
||||
end
|
||||
@ -220,12 +223,40 @@ end
|
||||
--------------------------------------
|
||||
--Get world position relative to plan position
|
||||
--------------------------------------
|
||||
function plan_class:get_world_pos(pos, anchor_pos)
|
||||
function plan_class:get_world_pos(plan_pos, anchor_pos)
|
||||
local apos = anchor_pos or self.anchor_pos
|
||||
return { x=pos.x+apos.x,
|
||||
y=pos.y+apos.y - self.data.ground_y - 1,
|
||||
z=pos.z+apos.z
|
||||
}
|
||||
local pos
|
||||
if self.mirrored then
|
||||
pos = table.copy(plan_pos)
|
||||
pos.x = -pos.x
|
||||
else
|
||||
pos = plan_pos
|
||||
end
|
||||
local facedir_rotated = {
|
||||
[0] = function(pos,apos) return {
|
||||
x=pos.x+apos.x,
|
||||
y=pos.y+apos.y,
|
||||
z=pos.z+apos.z,
|
||||
}end,
|
||||
[1] = function(pos,apos) return {
|
||||
x=pos.z+apos.x,
|
||||
y=pos.y+apos.y,
|
||||
z=-pos.x+apos.z,
|
||||
} end,
|
||||
[2] = function(pos,apos) return {
|
||||
x=-pos.x+apos.x,
|
||||
y=pos.y+apos.y,
|
||||
z=-pos.z+apos.z,
|
||||
} end,
|
||||
[3] = function(pos,apos) return {
|
||||
x=-pos.z+apos.x,
|
||||
y=pos.y+apos.y,
|
||||
z=pos.x+apos.z,
|
||||
} end,
|
||||
}
|
||||
local ret = facedir_rotated[self.facedir](pos, apos)
|
||||
ret.y = ret.y - self.data.ground_y - 1
|
||||
return ret
|
||||
end
|
||||
|
||||
--------------------------------------
|
||||
@ -295,12 +326,37 @@ end
|
||||
--------------------------------------
|
||||
--Get plan position relative to world position
|
||||
--------------------------------------
|
||||
function plan_class:get_plan_pos(pos, anchor_pos)
|
||||
function plan_class:get_plan_pos(world_pos, anchor_pos)
|
||||
local apos = anchor_pos or self.anchor_pos
|
||||
return { x=pos.x-apos.x,
|
||||
y=pos.y-apos.y + self.data.ground_y + 1,
|
||||
local facedir_rotated = {
|
||||
[0] = function(pos,apos) return {
|
||||
x=pos.x-apos.x,
|
||||
y=pos.y-apos.y,
|
||||
z=pos.z-apos.z
|
||||
}
|
||||
} end,
|
||||
[1] = function(pos,apos) return {
|
||||
x=-(pos.z-apos.z),
|
||||
y=pos.y-apos.y,
|
||||
z=(pos.x-apos.x),
|
||||
} end,
|
||||
[2] = function(pos,apos) return {
|
||||
x=-(pos.x-apos.x),
|
||||
y=pos.y-apos.y,
|
||||
z=-(pos.z-apos.z),
|
||||
} end,
|
||||
[3] = function(pos,apos) return {
|
||||
x=pos.z-apos.z,
|
||||
y=pos.y-apos.y,
|
||||
z=-(pos.x-apos.x),
|
||||
} end,
|
||||
}
|
||||
local ret = facedir_rotated[self.facedir](world_pos, apos)
|
||||
|
||||
if self.mirrored then
|
||||
ret.x = -ret.x
|
||||
end
|
||||
ret.y = ret.y + self.data.ground_y + 1
|
||||
return ret
|
||||
end
|
||||
|
||||
--------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user