forked from mtcontrib/maidroid
First commit
This commit is contained in:
64
modules/_aux.lua
Normal file
64
modules/_aux.lua
Normal file
@ -0,0 +1,64 @@
|
||||
------------------------------------------------------------
|
||||
-- Copyright (c) 2016 tacigar
|
||||
-- https://github.com/tacigar/maidroid
|
||||
------------------------------------------------------------
|
||||
|
||||
-- いい感じにモジュール化出来ないので名前空間に隠す
|
||||
maidroid.modules._aux = {}
|
||||
|
||||
-- 向いている方向と速度ベクトルを変える
|
||||
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)
|
||||
self.object:setvelocity(vel)
|
||||
self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2)
|
||||
end
|
||||
|
||||
-- yawから向いている方向ベクトルを得る
|
||||
function maidroid.modules._aux.get_forward(yaw)
|
||||
return { x = math.sin(yaw), y = 0.0, z = -math.cos(yaw) }
|
||||
end
|
||||
|
||||
-- 方向ベクトルを丸める
|
||||
function maidroid.modules._aux.get_round_forward(forward)
|
||||
local rforward = { x = 0, y = 0, z = 0}
|
||||
if math.abs((forward.x / (math.abs(forward.x) + math.abs(forward.z)))) > 0.5 then
|
||||
if forward.x > 0 then rforward.x = 1
|
||||
else rforward.x = -1 end
|
||||
end
|
||||
if math.abs((forward.z / (math.abs(forward.x) + math.abs(forward.z)))) > 0.5 then
|
||||
if forward.z > 0 then rforward.z = 1
|
||||
else rforward.z = -1 end
|
||||
end
|
||||
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
|
||||
|
||||
-- 落ちているアイテムを拾う
|
||||
function maidroid.modules._aux.get_item(self, radius, target_pred)
|
||||
local pos = self.object:getpos()
|
||||
local pred = target_list or (function() return true end)
|
||||
local all_objects = minetest.get_objects_inside_radius(pos, radius)
|
||||
for _, obj in ipairs(all_objects) do
|
||||
if not obj:is_player() and obj:get_luaentity() then
|
||||
local itemstring = obj:get_luaentity().itemstring
|
||||
if itemstring then
|
||||
if pred(itemstring) then
|
||||
local inv = maidroid._aux.get_maidroid_inventory(self)
|
||||
local stack = ItemStack(itemstring)
|
||||
local leftover = inv:add_item("main", stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
72
modules/chasing_player_module.lua
Normal file
72
modules/chasing_player_module.lua
Normal file
@ -0,0 +1,72 @@
|
||||
------------------------------------------------------------
|
||||
-- Copyright (c) 2016 tacigar
|
||||
-- https://github.com/tacigar/maidroid
|
||||
------------------------------------------------------------
|
||||
|
||||
local util = maidroid.util
|
||||
local _aux = maidroid.modules._aux
|
||||
|
||||
local state = { idle = 0, chase = 1}
|
||||
local view_of_range = 7 -- 発見可能距離
|
||||
local stop_of_range = 2 -- 止まる距離
|
||||
|
||||
-- プレーヤを追跡するだけのモジュール
|
||||
maidroid.register_module("maidroid:chasing_player_module", {
|
||||
description = "Maidroid Module : Chasing Player",
|
||||
inventory_image = "maidroid_chasing_player_module.png",
|
||||
initialize = function(self)
|
||||
self.state = state.idle
|
||||
self.object:setacceleration{x = 0, y = -10, z = 0}
|
||||
self.object:setvelocity{x = 0, y = 0, z = 0}
|
||||
end,
|
||||
finalize = function(self)
|
||||
self.state = nil
|
||||
self.object:setvelocity{x = 0, y = 0, z = 0}
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
local all_objects = minetest.get_objects_inside_radius(pos, view_of_range)
|
||||
local player = nil
|
||||
for _, obj in pairs(all_objects) do
|
||||
if obj:is_player() then player = obj; break end
|
||||
end
|
||||
if not player then
|
||||
self.object:set_animation(maidroid.animations.stand, 15, 0)
|
||||
self.state = state.idle
|
||||
return
|
||||
end
|
||||
local ppos = player:getpos()
|
||||
local dir = vector.subtract(ppos, pos)
|
||||
local vel = self.object:getvelocity()
|
||||
if (vector.length(dir) < stop_of_range) then
|
||||
if self.state == state.chase then
|
||||
self.object:set_animation(maidroid.animations.stand, 15, 0)
|
||||
self.state = state.idle
|
||||
self.object:setvelocity({x = 0, y = vel.y, z = 0})
|
||||
end
|
||||
else
|
||||
if self.state == state.idle then
|
||||
self.object:set_animation(maidroid.animations.walk, 15, 0)
|
||||
self.state = state.chase
|
||||
end
|
||||
self.object:setvelocity({x = dir.x, y = vel.y, z = dir.z})
|
||||
end
|
||||
local yaw = math.atan2(dir.z, dir.x) + math.pi/2
|
||||
self.object:setyaw(yaw)
|
||||
-- jump process
|
||||
if vel.y == 0 and self.state == state.chase then
|
||||
local rdir = vector.round(dir)
|
||||
local front_vec = { x = 0, y = 0, z = 0 }
|
||||
if math.abs((rdir.x / (math.abs(rdir.x) + math.abs(rdir.z)))) > 0.5 then
|
||||
if rdir.x > 0 then front_vec.x = 1 else front_vec.x = -1 end
|
||||
end
|
||||
if math.abs((rdir.z / (math.abs(rdir.x) + math.abs(rdir.z)))) > 0.5 then
|
||||
if rdir.z > 0 then front_vec.z = 1 else front_vec.z = -1 end
|
||||
end
|
||||
local front_pos = vector.add(vector.round(pos), front_vec)
|
||||
if minetest.get_node(front_pos).name ~= "air" then
|
||||
self.object:setvelocity({x = dir.x, y = 5, z = dir.z})
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
125
modules/farming_module.lua
Normal file
125
modules/farming_module.lua
Normal file
@ -0,0 +1,125 @@
|
||||
------------------------------------------------------------
|
||||
-- Copyright (c) 2016 tacigar
|
||||
-- https://github.com/tacigar/maidroid
|
||||
------------------------------------------------------------
|
||||
|
||||
local _aux = maidroid.modules._aux
|
||||
local state = {walk = 0, punch = 1, plant = 2}
|
||||
|
||||
-- 各植物ノードの種類の最大番号を探し出す
|
||||
local target_plants_list = {}
|
||||
minetest.after(0, function()
|
||||
local max = {}
|
||||
for name, node in pairs(minetest.registered_nodes) do
|
||||
if minetest.get_item_group(name, "plant") > 0 then
|
||||
local s, i = string.match(name, "(.+)_(%d+)")
|
||||
if max[s] == nil or max[s] < i then max[s] = i end
|
||||
end
|
||||
end
|
||||
for s, i in pairs(max) do
|
||||
table.insert(target_plants_list, s.."_"..i)
|
||||
end
|
||||
end)
|
||||
|
||||
local max_punch_time = 20
|
||||
local max_plant_time = 15
|
||||
|
||||
-- 種を持っているか否かを確認する
|
||||
local function has_seed_item(self)
|
||||
local inv = maidroid._aux.get_maidroid_inventory(self)
|
||||
local stacks = inv:get_list("main")
|
||||
for _, stack in ipairs(stacks) do
|
||||
local item_name = stack:get_name()
|
||||
if minetest.get_item_group(item_name, "seed") > 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 農業を行うモジュール
|
||||
maidroid.register_module("maidroid:farming_module", {
|
||||
description = "Maidroid Module : Farming",
|
||||
inventory_image = "maidroid_farming_module.png",
|
||||
initialize = function(self)
|
||||
self.object:set_animation(maidroid.animations.walk, 15, 0)
|
||||
self.object:setacceleration{x = 0, y = -10, z = 0}
|
||||
self.state = state.walk
|
||||
self.preposition = self.object:getpos()
|
||||
self.time_count = 0
|
||||
_aux.change_dir(self)
|
||||
end,
|
||||
finalize = function(self)
|
||||
self.state = nil
|
||||
self.preposition = nil
|
||||
self.time_count = 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 yaw = self.object:getyaw()
|
||||
local forward_vec = _aux.get_forward(yaw)
|
||||
local forward_vec2 = _aux.get_round_forward(forward_vec)
|
||||
local forward_pos = vector.add(rpos, forward_vec2)
|
||||
local forward_node = minetest.get_node(forward_pos)
|
||||
local forward_under_pos = vector.subtract(forward_pos, {x = 0, y = 1, z = 0})
|
||||
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}
|
||||
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(inetest.get_node(forward_under_pos).name, "wet") > 0
|
||||
and has_seed_item(self) then
|
||||
self.state = state.plant
|
||||
self.object:set_animation(maidroid.animations.mine, 15, 0)
|
||||
self.object:setvelocity{x = 0, y = 0, z = 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
|
||||
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
|
||||
end
|
||||
end
|
||||
self.preposition = pos
|
||||
return
|
||||
end
|
||||
})
|
132
modules/lumberjack_module.lua
Normal file
132
modules/lumberjack_module.lua
Normal file
@ -0,0 +1,132 @@
|
||||
------------------------------------------------------------
|
||||
-- Copyright (c) 2016 tacigar
|
||||
-- https://github.com/tacigar/maidroid
|
||||
------------------------------------------------------------
|
||||
|
||||
local util = maidroid.util
|
||||
local _aux = maidroid.modules._aux
|
||||
|
||||
local state = {walk = 0, plant = 1, punch = 2}
|
||||
local max_punch_time = 20
|
||||
local max_plant_time = 20
|
||||
local target_tree_list = { "default:tree" }
|
||||
local target_sapling_list = { "default:sapling" }
|
||||
|
||||
-- punchを始める必要があるか否かを調べる
|
||||
local function check_punch_flag(forward_pos)
|
||||
local forward_upper_pos = util.table_shallow_copy(forward_pos)
|
||||
while true do
|
||||
local forward_upper_node = minetest.get_node(forward_upper_pos)
|
||||
if util.table_find_value(target_tree_list, forward_upper_node.name) then
|
||||
return true, forward_upper_pos, forward_upper_node
|
||||
elseif forward_upper_node.name ~= "air" then break end
|
||||
forward_upper_pos.y = forward_upper_pos.y + 1
|
||||
end
|
||||
return false, nil, nil
|
||||
end
|
||||
|
||||
-- 苗木を持っているかを調べる
|
||||
local function has_sapling_item(self)
|
||||
local inv = maidroid._aux.get_maidroid_inventory(self)
|
||||
local stacks = inv:get_list("main")
|
||||
for _, stack in ipairs(stacks) do
|
||||
local item_name = stack:get_name()
|
||||
if util.table_find_value(target_sapling_list, item_name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 木こりモジュールを登録する
|
||||
maidroid.register_module("maidroid:lumberjack", {
|
||||
description = "Maidroid Module : Lumberjack",
|
||||
inventory_image = "maidroid_lumberjack_module.png",
|
||||
initialize = function(self)
|
||||
self.state = state.walk
|
||||
self.time_count = 0
|
||||
self.object:setacceleration{x = 0, y = -10, z = 0}
|
||||
self.object:set_animation(maidroid.animations.walk, 15, 0)
|
||||
self.preposition = self.object:getpos()
|
||||
_aux.change_dir(self)
|
||||
end,
|
||||
finalize = function(self)
|
||||
self.state = nil
|
||||
self.time_count = nil
|
||||
self.preposition = 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 yaw = self.object:getyaw()
|
||||
local forward = _aux.get_forward(yaw)
|
||||
local rforward = _aux.get_round_forward(forward)
|
||||
local forward_pos = vector.add(rpos, rforward)
|
||||
local forward_node = minetest.get_node(forward_pos)
|
||||
local forward_under_pos = _aux.get_under_pos(forward_pos)
|
||||
local forward_under_node = minetest.get_node(forward_under_pos)
|
||||
if self.state == state.walk then
|
||||
if check_punch_flag(forward_pos) then -- punch tree node
|
||||
self.state = state.punch
|
||||
self.object:set_animation(maidroid.animations.mine, 15, 0)
|
||||
self.object:setvelocity{x = 0, y = 0, z = 0}
|
||||
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(forward_under_node.name, "soil") > 0
|
||||
and has_sapling_item(self) then
|
||||
self.state = state.plant
|
||||
self.object:set_animation(maidroid.animations.mine, 15, 0)
|
||||
self.object:setvelocity{x = 0, y = 0, z = 0}
|
||||
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
|
||||
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
|
||||
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
|
||||
end
|
||||
self.preposition = pos
|
||||
end
|
||||
})
|
Reference in New Issue
Block a user