diff --git a/crafts.lua b/crafts.lua new file mode 100644 index 0000000..a7c2b0a --- /dev/null +++ b/crafts.lua @@ -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"} + } +}) diff --git a/depends.txt b/depends.txt index 1810f69..2b30af7 100644 --- a/depends.txt +++ b/depends.txt @@ -1 +1,3 @@ default +basic_materials? +luxury_decor? diff --git a/functions.lua b/functions.lua index 0a50e0a..3e95a10 100644 --- a/functions.lua +++ b/functions.lua @@ -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 diff --git a/init.lua b/init.lua index 99e3ce8..c598fe0 100644 --- a/init.lua +++ b/init.lua @@ -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") diff --git a/models/fiery_dart.b3d b/models/fiery_dart.b3d new file mode 100644 index 0000000..1515410 Binary files /dev/null and b/models/fiery_dart.b3d differ diff --git a/models/fiery_dart.blend b/models/fiery_dart.blend new file mode 100644 index 0000000..23e3c2b Binary files /dev/null and b/models/fiery_dart.blend differ diff --git a/models/fiery_dart.blend1 b/models/fiery_dart.blend1 new file mode 100644 index 0000000..0c2f1d8 Binary files /dev/null and b/models/fiery_dart.blend1 differ diff --git a/models/turret_unfold.blend b/models/turret_unfold.blend new file mode 100644 index 0000000..08c7c4d Binary files /dev/null and b/models/turret_unfold.blend differ diff --git a/models/turret_unfold.blend1 b/models/turret_unfold.blend1 new file mode 100644 index 0000000..b2fa250 Binary files /dev/null and b/models/turret_unfold.blend1 differ diff --git a/models/turret_unfold2.b3d b/models/turret_unfold2.b3d new file mode 100644 index 0000000..b63c070 Binary files /dev/null and b/models/turret_unfold2.b3d differ diff --git a/models/turret_unfold2.blend b/models/turret_unfold2.blend new file mode 100644 index 0000000..4f2ecd7 Binary files /dev/null and b/models/turret_unfold2.blend differ diff --git a/models/turret_unfold2.blend1 b/models/turret_unfold2.blend1 new file mode 100644 index 0000000..9f17aa3 Binary files /dev/null and b/models/turret_unfold2.blend1 differ diff --git a/register.lua b/register.lua new file mode 100644 index 0000000..e091e14 --- /dev/null +++ b/register.lua @@ -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" +}) diff --git a/textures/red_led.png b/textures/red_led.png new file mode 100644 index 0000000..bbf4c4c Binary files /dev/null and b/textures/red_led.png differ diff --git a/textures/turret.png b/textures/turret.png index a1098d2..7487745 100644 Binary files a/textures/turret.png and b/textures/turret.png differ diff --git a/textures/turret_eye.png b/textures/turret_eye.png new file mode 100644 index 0000000..b586278 Binary files /dev/null and b/textures/turret_eye.png differ diff --git a/textures/turret_fiery_dart.png b/textures/turret_fiery_dart.png new file mode 100644 index 0000000..94004be Binary files /dev/null and b/textures/turret_fiery_dart.png differ