diff --git a/_aux.lua b/_aux.lua index 0befa5b..db3b264 100644 --- a/_aux.lua +++ b/_aux.lua @@ -12,4 +12,3 @@ function maidroid._aux.get_maidroid_inventory(self) name = self.invname, } end - diff --git a/api.lua b/api.lua index 48962c1..a4a625b 100644 --- a/api.lua +++ b/api.lua @@ -149,7 +149,6 @@ function maidroid.register_maidroid(product_name, def) inventory_image = def.inventory_image, stack_max = 1, on_use = function(itemstack, user, pointed_thing) - print(pointed_thing.under, pointed_thing.above) if pointed_thing.above ~= nil then minetest.add_entity(pointed_thing.above, product_name) return itemstack diff --git a/modules/_aux.lua b/modules/_aux.lua index 2ed6840..19d5149 100644 --- a/modules/_aux.lua +++ b/modules/_aux.lua @@ -5,11 +5,22 @@ maidroid.modules._aux = {} +local velocity = 3 + +-- change direction to destination and velocity vector +function maidroid.modules._aux.change_dir_to(self, dest) + local pos = self.object:getpos() + local dir = vector.subtract(dest, pos) + local vel = vector.multiply(vector.normalize(dir), velocity) + self.object:setvelocity(vel) + self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2) +end + -- change direction and velocity vector function maidroid.modules._aux.change_dir(self) local rnd = function() return math.random(0, 5) * 2 - 5 end local dir = {x = rnd(), y = 0, z = rnd()} - local vel = vector.multiply(vector.normalize(dir), 3) + local vel = vector.multiply(vector.normalize(dir), velocity) self.object:setvelocity(vel) self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2) end @@ -33,10 +44,12 @@ function maidroid.modules._aux.get_round_forward(forward) return rforward end + function maidroid.modules._aux.get_under_pos(vec) return { x = vec.x, y = vec.y - 1, z = vec.z } end + function maidroid.modules._aux.get_upper_pos(vec) return { x = vec.x, y = vec.y + 1, z = vec.z } end @@ -62,3 +75,18 @@ function maidroid.modules._aux.pickup_item(self, radius, target_pred) end end end + +-- search surrounding nodes +function maidroid.modules._aux.search_surrounding(self, lenvec, pred) + local pos = vector.round(self.object:getpos()) + for xi = -lenvec.x, lenvec.x do + for yi = -lenvec.y, lenvec.y do + for zi = -lenvec.z, lenvec.z do + local p = {x = pos.x + xi, y = pos.y + yi, z = pos.z + zi} + local node = minetest.get_node(pos) + if pred(self, p, node) then return true, p, node end + end + end + end + return false, nil, nil +end diff --git a/modules/farming_module.lua b/modules/farming_module.lua index 8ff8470..bea6d86 100644 --- a/modules/farming_module.lua +++ b/modules/farming_module.lua @@ -4,7 +4,18 @@ ------------------------------------------------------------ local _aux = maidroid.modules._aux -local state = {walk = 0, punch = 1, plant = 2} + +local state = { + walk = 0, + punch = 1, + plant = 2, + walk_to_plant = 3, + walk_to_soil = 4, +} +local max_punch_time = 20 +local max_plant_time = 15 +local search_lenvec = {x = 3, y = 0, z = 3} + -- find max size of each plants local target_plants_list = {} @@ -21,8 +32,6 @@ minetest.after(0, function() end end) -local max_punch_time = 20 -local max_plant_time = 15 -- check the maidroid has seed items local function has_seed_item(self) @@ -37,6 +46,35 @@ local function has_seed_item(self) return false end + +-- check can plant plants. +local function can_plant(self, pos) + local node = minetest.get_node(pos) + local upos = _aux.get_under_pos(pos) + local unode = minetest.get_node(upos) + return node.name == "air" + and minetest.get_item_group(unode.name, "wet") > 0 + and has_seed_item(self) +end + + +-- check can punch plant +local function can_punch(self, pos) + local node = minetest.get_node(pos) + return maidroid.util.table_find_value(target_plants_list, node.name) +end + + +-- change state to walk +local function to_walk(self) + self.state = state.walk + self.destination = nil + self.object:set_animation(maidroid.animations.walk, 15, 0) + self.time_count = 0 + _aux.change_dir(self) +end + + maidroid.register_module("maidroid:farming_module", { description = "Maidroid Module : Farming", inventory_image = "maidroid_farming_module.png", @@ -47,6 +85,7 @@ maidroid.register_module("maidroid:farming_module", { self.state = state.walk self.preposition = self.object:getpos() self.time_count = 0 + self.destination = nil -- for walk_to_* _aux.change_dir(self) end, @@ -54,12 +93,14 @@ maidroid.register_module("maidroid:farming_module", { self.state = nil self.preposition = nil self.time_count = nil + self.destination = nil self.object:setvelocity{x = 0, y = 0, z = 0} end, on_step = function(self, dtime) local pos = self.object:getpos() local rpos = vector.round(pos) + local upos = _aux.get_under_pos(pos) local yaw = self.object:getyaw() local forward_vec = _aux.get_forward(yaw) local forward_vec2 = _aux.get_round_forward(forward_vec) @@ -67,69 +108,91 @@ maidroid.register_module("maidroid:farming_module", { local forward_node = minetest.get_node(forward_pos) local forward_under_pos = vector.subtract(forward_pos, {x = 0, y = 1, z = 0}) + _aux.pickup_item(self, 1.5, function(itemstring) -- pickup droped seed items + return minetest.get_item_group(itemstring, "seed") > 0 + end) if self.state == state.walk then -- searching plants or spaces - if maidroid.util.table_find_value(target_plants_list, forward_node.name) then - self.state = state.punch - self.object:set_animation(maidroid.animations.mine, 15, 0) - self.object:setvelocity{x = 0, y = 0, z = 0} + local b1, dest1 = _aux.search_surrounding(self, search_lenvec, can_plant) + local b2, dest2 = _aux.search_surrounding(self, search_lenvec, can_punch) + -- search soil node near + if b1 then -- to soil + self.state = state.walk_to_soil + self.destination = dest1 + _aux.change_dir_to(self, dest1) + elseif b2 then + self.state = state.walk_to_plant + self.destination = dest2 + _aux.change_dir_to(self, dest2) elseif pos.x == self.preposition.x or pos.z == self.preposition.z then _aux.change_dir(self) - elseif forward_node.name == "air" - and minetest.get_item_group(minetest.get_node(forward_under_pos).name, "wet") > 0 - and has_seed_item(self) then + end + + elseif self.state == state.punch then + if self.time_count >= max_punch_time then + if can_punch(self, self.destination) then + local destnode = minetest.get_node(self.destination) + minetest.remove_node(self.destination) + local inv = minetest.get_inventory{type = "detached", name = self.invname} + local stacks = minetest.get_node_drops(destnode.name) + for _, stack in ipairs(stacks) do + local leftover = inv:add_item("main", stack) + minetest.add_item(self.destination, leftover) + end + end + to_walk(self) + else + self.time_count = self.time_count + 1 + end + + elseif self.state == state.plant then + if self.time_count >= max_plant_time then + if can_plant(self, self.destination) then + local inv = minetest.get_inventory{type = "detached", name = self.invname} + local stacks = inv:get_list("main") + for idx, stack in ipairs(stacks) do + local item_name = stack:get_name() + if minetest.get_item_group(item_name, "seed") > 0 then + minetest.add_node(self.destination, {name = item_name, param2 = 1}) + stack:take_item(1) + inv:set_stack("main", idx, stack) + break + end + end + end + to_walk(self) + else + self.time_count = self.time_count + 1 + end + + elseif self.state == state.walk_to_soil then + if vector.distance(pos, self.destination) < 1.5 then -- to plant state + local destnode = minetest.get_node(self.destination) + if (can_plant(self, self.destination)) then self.state = state.plant self.object:set_animation(maidroid.animations.mine, 15, 0) self.object:setvelocity{x = 0, y = 0, z = 0} - end - -- pickup droped seed items - _aux.pickup_item(self, 1.5, function(itemstring) - return minetest.get_item_group(itemstring, "seed") > 0 - end) - - elseif self.state == state.punch then - if self.time_count >= max_punch_time then - if maidroid.util.table_find_value(target_plants_list, forward_node.name) then - minetest.remove_node(forward_pos) - local inv = minetest.get_inventory{type = "detached", name = self.invname} - local stacks = minetest.get_node_drops(forward_node.name) - for _, stack in ipairs(stacks) do - local leftover = inv:add_item("main", stack) - minetest.add_item(forward_pos, leftover) - end - end - self.state = state.walk - self.object:set_animation(maidroid.animations.walk, 15, 0) - self.time_count = 0 - _aux.change_dir(self) - else - self.time_count = self.time_count + 1 - end - - elseif self.state == state.plant then - if self.time_count >= max_plant_time then - if forward_node.name == "air" and minetest.get_item_group( - minetest.get_node(forward_under_pos).name, "soil") > 0 then - local inv = minetest.get_inventory{type = "detached", name = self.invname} - local stacks = inv:get_list("main") - for idx, stack in ipairs(stacks) do - local item_name = stack:get_name() - if minetest.get_item_group(item_name, "seed") > 0 then - minetest.add_node(forward_pos, {name = item_name, param2 = 1}) - stack:take_item(1) - inv:set_stack("main", idx, stack) - break - end - end - end - self.state = state.walk - self.object:set_animation(maidroid.animations.walk, 15, 0) - self.time_count = 0 - _aux.change_dir(self) - else - self.time_count = self.time_count + 1 + else to_walk(self) end + else + if pos.x == self.preposition.x or pos.z == self.preposition.z then + to_walk(self) + end + end + + elseif self.state == state.walk_to_plant then + if vector.distance(pos, self.destination) < 1.5 then + local destnode = minetest.get_node(self.destination) + if maidroid.util.table_find_value(target_plants_list, destnode.name) then + self.state = state.punch + self.object:set_animation(maidroid.animations.mine, 15, 0) + self.object:setvelocity{x = 0, y = 0, z = 0} + else to_walk(self) end + else + if pos.x == self.preposition.x or pos.z == self.preposition.z then + to_walk(self) end end - self.preposition = pos - return end - }) + self.preposition = pos + return + end +}) diff --git a/modules/lumberjack_module.lua b/modules/lumberjack_module.lua index 25faafd..942f8b6 100644 --- a/modules/lumberjack_module.lua +++ b/modules/lumberjack_module.lua @@ -88,54 +88,54 @@ maidroid.register_module("maidroid:lumberjack_module", { return util.table_find_value(target_sapling_list, itemstring) end) - elseif self.state == state.punch then - if self.time_count >= max_punch_time then - local punch_flag, forward_upper_pos, forward_upper_node - = check_punch_flag(forward_pos) - if punch_flag then - minetest.remove_node(forward_upper_pos) - local inv = minetest.get_inventory{type = "detached", name = self.invname} - local stacks = minetest.get_node_drops(forward_upper_node.name) - for _, stack in ipairs(stacks) do - local leftover = inv:add_item("main", stack) - minetest.add_item(forward_pos, leftover) - end + elseif self.state == state.punch then + if self.time_count >= max_punch_time then + local punch_flag, forward_upper_pos, forward_upper_node + = check_punch_flag(forward_pos) + if punch_flag then + minetest.remove_node(forward_upper_pos) + local inv = minetest.get_inventory{type = "detached", name = self.invname} + local stacks = minetest.get_node_drops(forward_upper_node.name) + for _, stack in ipairs(stacks) do + local leftover = inv:add_item("main", stack) + minetest.add_item(forward_pos, leftover) end - if (not forward_upper_pos) or (forward_upper_pos and - not check_punch_flag(_aux.get_upper_pos(forward_upper_pos))) then - self.state = state.walk - self.object:set_animation(maidroid.animations.walk, 15, 0) - _aux.change_dir(self) - end - self.time_count = 0 - else - self.time_count = self.time_count + 1 end - - elseif self.state == state.plant then - if self.time_count > max_plant_time then - if forward_node.name == "air" - and minetest.get_item_group(forward_under_node.name, "soil") > 0 then - local inv = minetest.get_inventory{type = "detached", name = self.invname} - local stacks = inv:get_list("main") - for i, stack in ipairs(stacks) do - local itemname = stack:get_name() - if util.table_find_value(target_sapling_list, itemname) then - minetest.add_node(forward_pos, {name = itemname, param2 = 1}) - stack:take_item(1) - inv:set_stack("main", i, stack) - break - end - end - end + if (not forward_upper_pos) or (forward_upper_pos and + not check_punch_flag(_aux.get_upper_pos(forward_upper_pos))) then self.state = state.walk self.object:set_animation(maidroid.animations.walk, 15, 0) - self.time_count = 0 _aux.change_dir(self) - else - self.time_count = self.time_count + 1 end + self.time_count = 0 + else + self.time_count = self.time_count + 1 + end + + elseif self.state == state.plant then + if self.time_count > max_plant_time then + if forward_node.name == "air" + and minetest.get_item_group(forward_under_node.name, "soil") > 0 then + local inv = minetest.get_inventory{type = "detached", name = self.invname} + local stacks = inv:get_list("main") + for i, stack in ipairs(stacks) do + local itemname = stack:get_name() + if util.table_find_value(target_sapling_list, itemname) then + minetest.add_node(forward_pos, {name = itemname, param2 = 1}) + stack:take_item(1) + inv:set_stack("main", i, stack) + break + end + end + end + self.state = state.walk + self.object:set_animation(maidroid.animations.walk, 15, 0) + self.time_count = 0 + _aux.change_dir(self) + else + self.time_count = self.time_count + 1 end - self.preposition = pos end - }) + self.preposition = pos + end +})