Added crafting recipes, improving/fixing shooting API, files splits

master
Andrey 2020-11-29 20:04:02 +03:00
parent 6d318ad4c2
commit 3786aa1a77
17 changed files with 248 additions and 457 deletions

45
crafts.lua Normal file
View File

@ -0,0 +1,45 @@
-- CRAFTINGS --
if minetest.get_modpath("basic_materials") then
minetest.register_craft({
output = "turret:turret_off",
recipe = {
{"basic_materials:plastic_sheet", "basic_materials:ic", "basic_materials:steel_bar"},
{"basic_materials:plastic_sheet", "turret:turret_eye", "basic_materials:steel_bar"},
{"basic_materials:plastic_sheet", "dye:black", "basic_materials:steel_bar"}
}
})
minetest.register_craft({
type = "shapeless",
output = "turret:red_led",
recipe = {"basic_materials:silicon", "basic_materials:plastic_sheet", "dye:red"}
})
elseif minetest.get_modpath("luxury_decor") then
minetest.register_craft({
output = "turret:turret_off",
recipe = {
{"luxury_decor:plastic_sheet", "default:steelblock", "luxury_decor:brass_stick"},
{"luxury_decor:plastic_sheet", "turret:turret_eye", "luxury_decor:brass_stick"},
{"luxury_decor:plastic_sheet", "dye:black", "luxury_decor:brass_stick"}
}
})
minetest.register_craft({
type = "shapeless",
output = "turret:red_led",
recipe = {"luxury_decor:wolfram_wire_reel", "luxury_decor:plastic_sheet", "dye:red"}
})
else
error("From 'turret' mod: No one required dependency is avaialble!")
end
minetest.register_craft({
output = "turret:turret_eye",
recipe = {
{"turret:red_led", "turret:red_led", "turret:red_led"},
{"turret:red_led", "xpanes:pane_flat", "turret:red_led"},
{"turret:red_led", "turret:red_led", "turret:red_led"}
}
})

View File

@ -1 +1,3 @@
default
basic_materials?
luxury_decor?

View File

@ -1,85 +1,26 @@
-- API FUNCTIONS --
target_objs = {}
local ANGLE_SPEED_RELEASE = 5 -- in degrees
local ANGLE_SPEED_DIRECT = 15 -- in degrees
DAMAGE = 2
--[[turret.init_ray = function(pos)
local dir = turret.get_turret_unitdir(pos)
local yaw = 0
if vector.angle(dir, {x=0, y=0, z=1}) == 0 or vector.angle(dir, {x=0, y=0, z=1}) == math.pi then
yaw = math.pi/2
end
local next_pos = vector.new(pos.x, pos.y+0.175, pos.z)
local ray_segments_list = {}
local next_obj = minetest.add_entity(next_pos, "turret:ray")
next_obj:set_properties({textures={"turret_ray_seg.png"}})
next_obj:set_yaw(yaw)
ray_segments_list[#ray_segments_list+1] = next_pos
next_obj = minetest.add_entity(next_pos, "turret:ray")
next_obj:set_properties({textures={"turret_ray_seg.png"}})
next_obj:set_rotation({x=math.pi/2, y=yaw, z=0})
ray_segments_list[#ray_segments_list+1] = next_pos
next_pos = vector.add(next_pos, dir)
local next_node = minetest.get_node(next_pos)
while next_node.name == "air" do
next_obj = minetest.add_entity(next_pos, "turret:ray")
next_obj:set_yaw(yaw)
ray_segments_list[#ray_segments_list+1] = next_pos
next_obj = minetest.add_entity(next_pos, "turret:ray")
next_obj:set_rotation({x=math.pi/2, y=yaw, z=0})
ray_segments_list[#ray_segments_list+1] = next_pos
next_pos = vector.add(next_pos, dir)
next_node = minetest.get_node(next_pos)
end
local meta = minetest.get_meta(pos)
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))
end]]
turret.spread_ray = function(pos, target_dir)
--pos.y = pos.y + 0.175
target_dir = vector.normalize(target_dir)
--[[local yaw = minetest.dir_to_yaw(new_ray_dir)+math.pi/2
local pitch = math.acos(vector.length({x=new_ray_dir.x, y=0, z=new_ray_dir.z})/vector.length(new_ray_dir))
local sign = new_ray_dir.y > 0 and -1 or 1
pitch = pitch*sign]]
local ray_segments_list = {}
local ray_rot = vector.dir_to_rotation(target_dir)
--local first_ray_seg_pos = vector.add(pos, vector.divide(target_dir, 4))
local next_obj = minetest.add_entity(pos, "turret:ray")
next_obj:set_properties({textures={"turret_ray_seg.png"}})
next_obj:set_rotation({x=ray_rot.x, y=ray_rot.y, z=0})
--minetest.debug("ANGLE: " .. math.deg(vector.angle(target_dir, vector.subtract(next_obj:get_pos(), pos))))
ray_segments_list[#ray_segments_list+1] = pos
--[[next_obj = minetest.add_entity(pos, "turret:ray")
next_obj:set_properties({textures={"turret_ray_seg.png"}})
next_obj:set_rotation({x=ray_rot.x+math.pi/2, y=ray_rot.y, z=ray_rot.z})
next_obj:set_yaw(ray_rot.y+math.pi/2)
ray_segments_list[#ray_segments_list+1] = pos]]
--[[next_obj:set_rotation({x=pitch, y=yaw, z=0})
next_obj2:set_rotation({x=pitch+math.pi/2, y=yaw, z=0})]]
local next_pos = vector.add(pos, target_dir)
local next_node = minetest.get_node(next_pos)
@ -88,152 +29,15 @@ turret.spread_ray = function(pos, target_dir)
next_obj:set_rotation({x=ray_rot.x, y=ray_rot.y, z=0})
ray_segments_list[#ray_segments_list+1] = next_pos
--[[next_obj = minetest.add_entity(next_pos, "turret:ray")
next_obj:set_rotation({x=ray_rot.x+math.pi/2, y=ray_rot.y, z=ray_rot.z})
next_obj:set_yaw(ray_rot.y+math.pi/2)
ray_segments_list[#ray_segments_list+1] = next_pos]]
next_pos = vector.add(next_pos, target_dir)
next_node = minetest.get_node(next_pos)
--minetest.debug("ANGLE: " .. math.deg(vector.angle(target_dir, vector.subtract(next_obj:get_pos(), pos))))
end
local meta = minetest.get_meta(pos)
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))
meta:set_string("ray_dir", minetest.serialize(target_dir))
end
--[[turret.get_ray_segment_from_pos = function(pos)
local objs = minetest.get_objects_inside_radius(pos, 0.1)
if not objs then return end
for _, obj in ipairs(objs) do
if obj:get_luaentity().name == "turret:ray" then
return obj
end
end
return
end]]
--[[turret.spread_ray = function(pos, unit_ray_dir, rot_axis, rot_step)
rot_step = rot_step or 0.0
pos = vector.add(pos, {x=0, y=0.175, z=0})
local meta = minetest.get_meta(pos)
local ray_seg_list = minetest.deserialize(meta:get_string("ray_segments_list"))]]
--[[local unit_z_dir = {x=1, y=0, z=0}
local cur_rot = {x=0,
y=vector.angle(unit_z_dir, {x=unit_ray_dir.x, y=0, z=unit_ray_dir.z}),
z=vector.angle(unit_z_dir, {x=unit_ray_dir.x, y=unit_ray_dir.y, z=0})
}
minetest.debug("cur_rot: y: " .. math.deg(cur_rot.y) .. ", z: " .. math.deg(cur_rot.z))
local rot_change = vector.new()]]
--[[local new_unit_ray_dir = {x=unit_ray_dir.x, y=unit_ray_dir.y, z=unit_ray_dir.z}
minetest.debug("unit_rot_dir: x: " .. new_unit_ray_dir.x .. ", y: " .. new_unit_ray_dir.y .. ", z: " .. new_unit_ray_dir.z)
if ray_seg_list and #ray_seg_list ~= 0 then
local found_objs = minetest.get_objects_inside_radius(ray_seg_list[1], 0.1)
local ray_obj
for _, obj in ipairs(found_objs) do
local self = obj:get_luaentity()
if self then
if self.name == "turret:ray" then
ray_obj = obj
end
end
end
if not ray_obj then return end
turret.delete_ray(pos)
new_unit_ray_dir = vector.rotate_around_axis(new_unit_ray_dir, rot_axis, rot_step)
minetest.debug("new_unit_ray_dir: x: " .. new_unit_ray_dir.x .. ", y: " .. new_unit_ray_dir.y .. ", z: " .. new_unit_ray_dir.z)]]
--[[local abs_rot = {x=0,
y=vector.angle(unit_z_dir, {x=new_unit_ray_dir.x, y=0, z=new_unit_ray_dir.z}),
z=vector.angle(unit_z_dir, {x=new_unit_ray_dir.x, y=new_unit_ray_dir.y, z=0})
}
minetest.debug("abs_rot: y: " .. math.deg(abs_rot.y) .. ", z: " .. math.deg(abs_rot.z))
rot_change = {y=abs_rot.y - cur_rot.y, z=abs_rot.z - cur_rot.z}
minetest.debug("rot_change: y: " .. math.deg(rot_change.y) .. ", z: " .. math.deg(rot_change.z))]]
--[[end
local ray_segments_list = {}
local ray_seg = minetest.add_entity(pos, "turret:ray")
ray_seg:set_properties({textures = {"turret_ray_seg.png"}})
local new_rot = vector.dir_to_rotation(new_unit_ray_dir)
new_rot.y = new_rot.y + math.pi/2
minetest.debug("new_rot: x: " .. new_rot.x .. ", y: " .. new_rot.y .. ", z: " .. new_rot.z)]]
--[[local cur_yaw = ray_seg:get_rotation().y
ray_seg:set_yaw(0)
ray_seg:set_rotation({x=0, y=0, z=new_rot.z})
ray_seg:set_yaw(new_rot.y)]]
--[[ray_seg:set_rotation(new_rot)
local cur_rot = ray_seg:get_rotation()
minetest.debug("cur_rot: x: " .. cur_rot.x .. ", y: " .. cur_rot.y .. ", z: " .. cur_rot.z)]]
--[[local cur_rot = ray_seg:get_rotation()
if vector.length(rot) ~= 0 then
ray_seg:set_rotation({x=cur_rot.x, y=cur_rot.y+rot+ang, z=cur_rot.z+rot.z})
else
ray_seg:set_rotation({x=0, y=ang, z=0})
end]]
--ray_segments_list[#ray_segments_list+1] = pos
--[[local next_pos = {x=u_dir_vec.x*math.cos(cur_rot.y+rot.y) - u_dir_vec.z*math.sin(cur_rot.y+rot.y),
y=u_dir_vec.y,
z=u_dir_vec.z*math.cos(cur_rot.y+rot.y) + u_dir_vec.x*math.sin(cur_rot.y+rot.y)
}
next_pos.x = next_pos.x*math.cos(rot.z) - u_dir_vec.y*math.sin(rot.z)
next_pos.y = next_pos.y*math.cos(rot.z) + u_dir_vec.x*math.sin(rot.z)
next_pos = vector.add(pos, next_pos)
local node = minetest.get_node(next_pos)]]
--[[local counter = 1
local next_pos = vector.add(pos, new_unit_ray_dir)
local node = minetest.get_node(next_pos)
while node.name == "air" do
if counter > 100 then
return true
end
local next_obj = minetest.add_entity(next_pos, "turret:ray")]]
--[[next_obj:set_yaw(0)
next_obj:set_rotation({x=0, y=0, z=new_rot.z})
next_obj:set_yaw(new_rot.y)]]
--[[next_obj:set_rotation(new_rot)
ray_segments_list[#ray_segments_list+1] = next_pos
counter = counter + 1
next_pos = vector.add(pos, vector.multiply(new_unit_ray_dir, counter))
node = minetest.get_node(next_pos)
end
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))
return true
end]]
turret.delete_ray = function(pos)
local meta = minetest.get_meta(pos)
@ -250,25 +54,7 @@ turret.delete_ray = function(pos)
end
end
end
--[[turret.rotate_obj_pos_around_center = function(center, unit_direction, obj, rotation)
if not obj or not obj:get_luaentity() then
return
end
local rel_obj_pos = vector.subtract(obj:get_pos(), center)
local cur_rot = {y=vector.angle({x=unit_direction.x, z=unit_direction.z}, {x=rel_obj_pos.x, z=rel_obj_pos.z}),
z=vector.angle({x=unit_direction.x, y=unit_direction.y}, {x=rel_obj_pos.x, y=rel_obj_pos.y})
}
local new_rot = {y=cur_rot.y + rotation.y, z=cur_rot.z + rotation.z}
if math.abs(math.deg(new_rot.y)) > 45 or math.abs(math.deg(new_rot.z)) > 45 then
return
end
end]]
turret.get_turret_unitdir = function(pos)
local node = minetest.get_node(pos)
local u_dir_vec = vector.rotate(minetest.facedir_to_dir(node.param2), {x=0, y=math.pi, z=0})
@ -286,27 +72,28 @@ turret.is_obj_inside_field_of_sight = function(pos, obj_pos)
return vector.length(rel_obj_pos) <= 20 and vector.angle(u_dir_vec, rel_obj_pos) <= math.rad(45)
end
vector.rotation = function(vec1, vec2)
return {x = vector.angle({x=0, y=vec1.y, z=vec1.z}, {x=0, y=vec2.y, z=vec2.z}),
y = vector.angle({x=vec1.x, y=0, z=vec1.z}, {x=vec2.x, y=0, z=vec2.z}),
z = vector.angle({x=vec1.x, y=vec1.y, z=0}, {x=vec2.x, y=vec2.y, z=0})
}
end
vector.are_co_directional = function(vec1, vec2)
return vector.angle(vec1, vec2) == 0
end
turret.get_state = function(pos)
local node = minetest.get_node(pos)
local state = node.name:match("_on$") or node.name:match("_off$")
return state and state:sub(2)
end
turret.direct_ray_to_entity = function(pos)
local meta = minetest.get_meta(pos)
local strpos = minetest.pos_to_string(pos)
local target_obj = target_objs[strpos]
local eye_pos = {x=pos.x, y=pos.y+0.175, z=pos.z}
local ray_seg_list = minetest.deserialize(meta:get_string("ray_segments_list"))
local u_dir_vec = turret.get_turret_unitdir(pos)
local cur_ray_dir = minetest.deserialize(meta:get_string("ray_dir"))
if not target_obj then
local node = minetest.get_node(pos)
local state = turret.get_state(pos)
if not target_objs[strpos] then
local nearby_objs = minetest.get_objects_inside_radius(eye_pos, 20)
local hit_objs = {}
@ -320,7 +107,7 @@ turret.direct_ray_to_entity = function(pos)
if #hit_objs == 0 then
--minetest.debug("Current ray dir: x: " .. ray_seg_list[1].x .. ", y: " .. ray_seg_list[1].y .. ", z: " .. ray_seg_list[1].z)
turret.delete_ray(pos)
turret.spread_ray(pos, vector.normalize(cur_ray_dir))
turret.spread_ray(eye_pos, vector.normalize(cur_ray_dir))
local rseg_l = minetest.deserialize(meta:get_string("ray_segments_list"))
--minetest.debug("Updated ray dir: x: " .. rseg_l[1].x .. ", y: " .. rseg_l[1].y .. ", z: " .. rseg_l[1].z)
@ -329,56 +116,89 @@ turret.direct_ray_to_entity = function(pos)
local rand_obj = hit_objs[math.random(1, #hit_objs)]
target_objs[strpos] = rand_obj
if state == "off" then
minetest.set_node(pos, {name=node.name:gsub("_off$", "_on"), param1=node.param1, param2=node.param2})
return true
end
else
local is_object_inside_view_radius = turret.is_obj_inside_field_of_sight(pos, target_obj:get_pos())
local is_object_inside_view_radius = turret.is_obj_inside_field_of_sight(pos, target_objs[strpos]:get_pos())
if not is_object_inside_view_radius then
target_objs[strpos] = nil
return
end
if vector.are_co_directional(vector.subtract(target_obj:get_pos(), eye_pos), cur_ray_dir) then
--minetest.debug("gdkjkdjgkjgdjkg")
--minetest.debug("angle: " .. math.deg(vector.angle(vector.subtract(target_objs[strpos]:get_pos(), eye_pos), cur_ray_dir)))
if vector.are_co_directional(vector.subtract(target_objs[strpos]:get_pos(), eye_pos), cur_ray_dir) then
minetest.debug("Turret has targeted!")
if state == "on" then
minetest.debug("Turret is shooting!")
turret.shoot(pos)
end
return true
end
end
local rel_tpos = vector.subtract(target_obj:get_pos(), eye_pos)
local rel_tpos = vector.subtract(target_objs[strpos]:get_pos(), eye_pos)
local pivot_vec = vector.cross(rel_tpos, cur_ray_dir)
local ang = vector.angle(cur_ray_dir, rel_tpos)
local new_ray_dir
if ang < math.rad(ANGLE_SPEED_DIRECT) then
new_ray_dir = vector.rotate_around_axis(cur_ray_dir, pivot_vec, ang)
minetest.debug("ang: " .. ang)
minetest.debug("ANGLE: " .. vector.angle(rel_tpos, new_ray_dir))
else
new_ray_dir = vector.rotate_around_axis(cur_ray_dir, pivot_vec, math.rad(ANGLE_SPEED_DIRECT))
end
turret.delete_ray(pos)
turret.spread_ray(pos, vector.normalize(new_ray_dir))
turret.spread_ray(eye_pos, vector.normalize(new_ray_dir))
end
turret.release = function(pos)
if target_objs[pos] then return end
if target_objs[minetest.pos_to_string(pos)] then return end
--minetest.debug("turret.release(): continue to return...")
local u_dir_vec = turret.get_turret_unitdir(pos)
--minetest.debug("turret.release(): continue1...")
local meta = minetest.get_meta(pos)
local ray_seg_list = minetest.deserialize(meta:get_string("ray_segments_list"))
local rel_ray_seg_dir = minetest.deserialize(meta:get_string("ray_dir"))
--minetest.debug("rel_ray_seg_dir: " .. minetest.pos_to_string(rel_ray_seg_dir))
--minetest.debug("u_dir_vec: " .. minetest.pos_to_string(u_dir_vec))
local ang = vector.angle(rel_ray_seg_dir, u_dir_vec)
--minetest.debug("turret.release(): continue2...")
if vector.are_co_directional(rel_ray_seg_dir, u_dir_vec) then
return true
else
local turn_step = (ang < math.rad(ANGLE_SPEED_RELEASE) and ang or math.rad(ANGLE_SPEED_RELEASE))
local pivot_vec = vector.cross(u_dir_vec, rel_ray_seg_dir)
local new_rseg_dir = vector.rotate_around_axis(rel_ray_seg_dir, pivot_vec, turn_step)
local turn_step = (ang < math.rad(ANGLE_SPEED_RELEASE) and ang or math.rad(ANGLE_SPEED_RELEASE))
local pivot_vec = vector.cross(u_dir_vec, rel_ray_seg_dir)
local new_rseg_dir = vector.rotate_around_axis(rel_ray_seg_dir, pivot_vec, turn_step)
turret.delete_ray(pos)
turret.spread_ray(pos, vector.normalize(new_rseg_dir))
turret.delete_ray(pos)
turret.spread_ray(pos, vector.normalize(new_rseg_dir))
rel_ray_seg_dir = minetest.deserialize(meta:get_string("ray_dir"))
if vector.are_co_directional(rel_ray_seg_dir, u_dir_vec) then
local node = minetest.get_node(pos)
minetest.set_node(pos, {name=node.name:gsub("_on$", "_off"), param1=node.param1, param2=node.param2})
end
end
turret.shoot = function(pos)
local node = minetest.get_node(pos)
if turret.get_state(pos) ~= "on" then return end
local ray_dir = minetest.deserialize(minetest.get_meta(pos):get_string("ray_dir"))
local vel = vector.multiply(ray_dir, 10)
local offset_horiz = {-0.2, 0.2}
local offset_vert = {-0.1, 0, 0.1}
local rand_offset = {x=offset_horiz[math.random(1, 2)], y=offset_vert[math.random(1, 2)]+0.175, z=0.1}
local yaw = vector.angle({x=0, y=0, z=1}, turret.get_turret_unitdir(pos))
local res_pos = vector.add(pos, vector.rotate(rand_offset, {x=0, y=yaw, z=0}))
local dart = minetest.add_entity(res_pos, "turret:fiery_dart")
local rot = vector.dir_to_rotation(ray_dir)
dart:set_rotation({x=rot.x, y=rot.y, z=0})
dart:set_velocity(vel)
end

210
init.lua
View File

@ -3,211 +3,5 @@ turret = {}
local modpath = minetest.get_modpath("turret")
dofile(modpath .. "/functions.lua")
minetest.register_entity("turret:ray", {
visual = "mesh",
visual_size = {x=5, y=5, z=5},
mesh = "ray_segment.b3d",
textures = {"turret_ray.png"},
collisionbox = {0, 0, 0, 0, 0, 0},
glow = 10
})
minetest.register_node("turret:turret", {
description = "Turret",
drawtype = "mesh",
mesh = "turret2.b3d",
tiles = {"turret.png"},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
collision_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
selection_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
groups = {cracky=2},
sounds = default.node_sound_metal_defaults(),
on_construct = function(pos)
--[[local node = minetest.get_node(pos)
local unit_dir = vector.rotate(minetest.facedir_to_dir(node.param2), {x=0, y=math.rad(180), z=0})]]
--[[turret.spread_ray(pos, unit_dir, {x=0, y=1, z=0})
local random_pos = {x=0, y=-2.0, z=13.4}
minetest.debug("angle_to_target: " .. math.deg(vector.angle(unit_dir, random_pos)))
local axis = vector.rotate(unit_dir, {x=0, y=math.pi/2, z=0})
minetest.debug("angle: " .. math.deg(vector.angle(unit_dir, axis)))]]
--turret.spread_ray(pos, unit_dir, axis, math.rad(-45))--math.asin(vector.length(axis)/(vector.length(unit_dir)*vector.length(random_pos))))
--[[local found_objs = minetest.get_objects_inside_radius(pos, 20)
local nearby_players = {}
if found_objs then
for _, obj in ipairs(found_objs) do
if obj:is_player() then
nearby_players[#nearby_players+1] = obj
end
end
if #nearby_players ~= 0 then
local random_tplayer = nearby_players[math.random(1, #nearby_players)]
local rel_pos = vector.subtract(random_tplayer:get_pos(), pos)
local axis = vector.cross(rel_pos, unit_dir)
local new_unit_dir = vector.rotate_around_axis(unit_dir, axis, vector.angle(unit_dir, rel_pos))
local ray_segments_list = {}
local ray_seg = minetest.add_entity(pos, "turret:ray")
ray_seg:set_properties({textures = {"turret_ray_seg.png"}})]]
--[[local target_unit_dir_yaw = minetest.dir_to_yaw(new_unit_dir)
--new_unit_dir = vector.rotate(new_unit_dir, {x=0, y=1, z=0}, -target_unit_dir_yaw)
minetest.debug("length1: " .. vector.length({x=new_unit_dir.x, y=0, z=new_unit_dir.z}))
minetest.debug("length2: " .. vector.length({x=new_unit_dir.x, y=new_unit_dir.y, z=0}))
local pitch = math.acos(vector.length({x=new_unit_dir.x, y=0, z=new_unit_dir.z})/vector.length({x=new_unit_dir.x, y=new_unit_dir.y, z=new_unit_dir.z}))
minetest.debug("pitch: " .. pitch)]]
--new_unit_dir = vector.rotate(new_unit_dir, {x=0, y=1, z=0}, target_unit_dir_yaw)
--ray_seg:set_rotation({x=pitch, y=target_unit_dir_yaw, z=0})
--ray_seg:set_rotation({x=new_dir_rot.x, y=new_dir_rot.y+math.pi/2, z=new_dir_rot.z})
--[[ray_segments_list[#ray_segments_list+1] = pos
local ray_seg2 = minetest.add_entity(pos, "turret:ray")
ray_seg2:set_properties({textures = {"turret_ray_seg.png"}})
--ray_seg2:set_rotation({x=pitch, y=target_unit_dir_yaw+math.pi/2, z=0})
--ray_seg2:set_rotation({x=new_dir_rot.x, y=new_dir_rot.y+math.pi/2, z=new_dir_rot.z+math.pi/2})
ray_segments_list[#ray_segments_list+1] = pos
local new_dir_rot = vector.dir_to_rotation(new_unit_dir, axis)
if vector.angle(unit_dir, {x=0, y=0, z=1}) == 0 or vector.angle(unit_dir, {x=0, y=0, z=1}) == math.pi then
ray_seg:set_yaw(math.pi/2)
ray_seg2:set_yaw(math.pi/2)
end
local ray_cur_rot = ray_seg:get_rotation()
local ray2_cur_rot = ray_seg2:get_rotation()
ray_seg:set_rotation(vector.add(ray_cur_rot, new_dir_rot))
ray_seg2:set_rotation(vector.add(ray2_cur_rot, new_dir_rot))
local counter = 1
local next_pos = vector.add(pos, new_unit_dir)
local node = minetest.get_node(next_pos)
while node.name == "air" do
local next_obj = minetest.add_entity(next_pos, "turret:ray")
--next_obj:set_yaw(minetest.dir_to_yaw(unit_dir)+math.pi/2)
--next_obj:set_rotation({x=pitch, y=target_unit_dir_yaw, z=0})
--next_obj:set_rotation(new_dir_rot)
ray_segments_list[#ray_segments_list+1] = next_pos
local next_obj2 = minetest.add_entity(next_pos, "turret:ray")
--next_obj2:set_rotation({x=pitch, y=target_unit_dir_yaw+math.pi/2, z=0})
--next_obj2:set_rotation({x=new_dir_rot.x, y=new_dir_rot.y, z=new_dir_rot.z+math.pi/2})
ray_segments_list[#ray_segments_list+1] = next_pos
if vector.angle(unit_dir, {x=0, y=0, z=1}) == 0 or vector.angle(unit_dir, {x=0, y=0, z=1}) == math.pi then
next_obj:set_yaw(math.pi/2)
next_obj2:set_rotation({x=0, y=math.pi/2, z=math.pi/2})
end
local nobj_cur_rot = next_obj:get_rotation()
local nobj2_cur_rot = next_obj2:get_rotation()
next_obj:set_rotation(vector.add(nobj_cur_rot, new_dir_rot))
next_obj2:set_rotation(vector.add(nobj2_cur_rot, new_dir_rot))
counter = counter + 1
next_pos = vector.add(pos, vector.multiply(new_unit_dir, counter))
node = minetest.get_node(next_pos)
end
local meta = minetest.get_meta(pos)
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))
end
end]]
--[[local meta = minetest.get_meta(pos)
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))
local axis = vector.rotate(unit_dir, {x=0, y=math.pi/2, z=0})
local new_unit_dir = vector.rotate_around_axis(unit_dir, axis, math.rad(-45))
local ray_segments_list = {}
local ray_seg = minetest.add_entity(pos, "turret:ray")
ray_seg:set_properties({textures = {"turret_ray_seg.png"}})
--ray_seg:set_yaw(minetest.dir_to_yaw(unit_dir)+math.pi/2)
ray_seg:set_rotation({x=0, y=minetest.dir_to_yaw(unit_dir)+math.pi/2, z=math.rad(-45)})
ray_segments_list[#ray_segments_list+1] = pos
local counter = 1
local next_pos = vector.add(pos, new_unit_dir)
local node = minetest.get_node(next_pos)
while node.name == "air" do
local next_obj = minetest.add_entity(next_pos, "turret:ray")
--next_obj:set_yaw(minetest.dir_to_yaw(unit_dir)+math.pi/2)
next_obj:set_rotation({x=0, y=minetest.dir_to_yaw(unit_dir)+math.pi/2, z=math.rad(-45)})
ray_segments_list[#ray_segments_list+1] = next_pos
counter = counter + 1
next_pos = vector.add(pos, vector.multiply(new_unit_dir, counter))
node = minetest.get_node(next_pos)
end
local meta = minetest.get_meta(pos)
meta:set_string("ray_segments_list", minetest.serialize(ray_segments_list))]]
--[[local timer = minetest.get_node_timer(pos)
timer:start(1)]]
--[[local found_objs = minetest.get_objects_inside_radius(pos, 20)
local nearby_players = {}
if found_objs then
for _, obj in ipairs(found_objs) do
if obj:is_player() then
nearby_players[#nearby_players+1] = obj
end
end
local random_player = nearby_players[math.random(1, #nearby_players)]
turret.spread_ray(pos, turret.get_turret_unitdir(pos), random_player:get_pos())
end]]
turret.spread_ray(pos, turret.get_turret_unitdir(pos))
local timer = minetest.get_node_timer(pos)
timer:start(0.05)
end,
on_destruct = function(pos)
turret.delete_ray(pos)
end,
on_timer = function(pos, elapsed)
local ray_dir = minetest.deserialize(minetest.get_meta(pos):get_string("ray_dir"))
--minetest.debug("target_objs[pos]: " .. tostring(target_objs[pos]))
--minetest.debug("angle: " .. math.deg(vector.angle(turret.get_turret_unitdir(pos), ray_dir)))
local dir = turret.get_turret_unitdir(pos)
dir.y = dir.y + 0.175
if not target_objs[pos] and not vector.are_co_directional(dir, ray_dir) then
--minetest.debug("turret.release():Returning to the original orientation...")
turret.release(pos)
end
turret.direct_ray_to_entity(pos)
return true
end
})
dofile(modpath .. "/register.lua")
dofile(modpath .. "/crafts.lua")

BIN
models/fiery_dart.b3d Normal file

Binary file not shown.

BIN
models/fiery_dart.blend Normal file

Binary file not shown.

BIN
models/fiery_dart.blend1 Normal file

Binary file not shown.

BIN
models/turret_unfold.blend Normal file

Binary file not shown.

BIN
models/turret_unfold.blend1 Normal file

Binary file not shown.

BIN
models/turret_unfold2.b3d Normal file

Binary file not shown.

BIN
models/turret_unfold2.blend Normal file

Binary file not shown.

Binary file not shown.

130
register.lua Normal file
View File

@ -0,0 +1,130 @@
-- REGISTRATIONS --
minetest.register_entity("turret:ray", {
visual = "mesh",
visual_size = {x=5, y=5, z=5},
mesh = "ray_segment.b3d",
textures = {"turret_ray.png"},
collisionbox = {0, 0, 0, 0, 0, 0},
glow = 10
})
minetest.register_entity("turret:fiery_dart", {
visual = "mesh",
visual_size = {x=25, y=25, z=25},
physical = true,
pointable = false,
mesh = "fiery_dart.b3d",
textures = {"turret_fiery_dart.png"},
collisionbox = {-0.05, -0.05, -0.15, 0.05, 0.05, 0.15},
selectionbox = {0, 0, 0, 0, 0, 0},
glow = 15,
on_step = function(self, dtime, moveresult)
if moveresult.collides then
local cols = moveresult.collisions
for _, collision in ipairs(cols) do
if collision.type == "object" then
collision.object:set_hp(collision.object:get_hp()-DAMAGE, "punch")
end
end
self.object:remove()
end
end
})
minetest.register_node("turret:turret_off", {
description = "Turret",
drawtype = "mesh",
mesh = "turret2.b3d",
tiles = {"turret.png"},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
collision_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
selection_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
groups = {cracky=2},
sounds = default.node_sound_metal_defaults(),
on_construct = function(pos)
turret.spread_ray(pos, turret.get_turret_unitdir(pos))
local timer = minetest.get_node_timer(pos)
timer:start(0.1)
end,
on_destruct = function(pos)
turret.delete_ray(pos)
end,
on_timer = function(pos, elapsed)
--[[local ray_dir = minetest.deserialize(minetest.get_meta(pos):get_string("ray_dir"))
local dir = turret.get_turret_unitdir(pos)
if not target_objs[pos] and not vector.are_co_directional(dir, ray_dir) then
turret.release(pos)
end]]
turret.direct_ray_to_entity(pos)
return true
end
})
minetest.register_node("turret:turret_on", {
description = "Turret",
drawtype = "mesh",
mesh = "turret_unfold2.b3d",
tiles = {"turret.png"},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
collision_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
selection_box = {
type = "fixed",
fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}
},
drop = "turret:turret_off",
groups = {cracky=2, not_in_creative_inventory=1},
sounds = default.node_sound_metal_defaults(),
on_construct = function(pos)
turret.spread_ray(pos, turret.get_turret_unitdir(pos))
local timer = minetest.get_node_timer(pos)
timer:start(0.1)
end,
on_destruct = function(pos)
turret.delete_ray(pos)
end,
on_timer = function(pos, elapsed)
local ray_dir = minetest.deserialize(minetest.get_meta(pos):get_string("ray_dir"))
local dir = turret.get_turret_unitdir(pos)
if not target_objs[minetest.pos_to_string(pos)] and not vector.are_co_directional(dir, ray_dir) then
minetest.debug("Release!")
turret.release(pos)
end
turret.direct_ray_to_entity(pos)
return true
end
})
minetest.register_craftitem("turret:turret_eye", {
description = "Turret Eye",
inventory_image = "turret_eye.png"
})
minetest.register_craftitem("turret:red_led", {
description = "Red LED",
inventory_image = "red_led.png"
})

BIN
textures/red_led.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
textures/turret_eye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB