space_to_tab

This commit is contained in:
tacigar 2016-09-13 09:48:17 +09:00
parent a46a55446f
commit c580c86ac0
10 changed files with 618 additions and 618 deletions

View File

@ -7,8 +7,8 @@ maidroid._aux = {}
-- get inventory of the maidroid -- get inventory of the maidroid
function maidroid._aux.get_maidroid_inventory(self) function maidroid._aux.get_maidroid_inventory(self)
return minetest.get_inventory{ return minetest.get_inventory{
type = "detached", type = "detached",
name = self.invname, name = self.invname,
} }
end end

256
api.lua
View File

@ -7,11 +7,11 @@ local _aux = maidroid._aux
-- aux function to generate serialnumber for inventories -- aux function to generate serialnumber for inventories
local gen_inv_serialnumber = (function () local gen_inv_serialnumber = (function ()
local serialnumber = 0 local serialnumber = 0
return function () return function ()
serialnumber = serialnumber + 1 serialnumber = serialnumber + 1
return serialnumber - 1 return serialnumber - 1
end end
end) () end) ()
local main_invsize = 16 local main_invsize = 16
@ -23,140 +23,140 @@ local module_invname = "module"
maidroid.registered_modules = {} maidroid.registered_modules = {}
function maidroid.register_module(module_name, def) function maidroid.register_module(module_name, def)
maidroid.registered_modules[module_name] = def maidroid.registered_modules[module_name] = def
minetest.register_craftitem(module_name, { minetest.register_craftitem(module_name, {
description = def.description, description = def.description,
stack_max = 1, stack_max = 1,
inventory_image = def.inventory_image, inventory_image = def.inventory_image,
}) })
end end
-- animation frame -- animation frame
maidroid.animations = { maidroid.animations = {
stand = {x = 0, y = 79}, stand = {x = 0, y = 79},
lay = {x = 162, y = 166}, lay = {x = 162, y = 166},
walk = {x = 168, y = 187}, walk = {x = 168, y = 187},
mine = {x = 189, y = 198}, mine = {x = 189, y = 198},
walk_mine = {x = 200, y = 219}, walk_mine = {x = 200, y = 219},
sit = {x = 81, y = 160}, sit = {x = 81, y = 160},
} }
function maidroid.register_maidroid(product_name, def) function maidroid.register_maidroid(product_name, def)
minetest.register_entity(product_name, { minetest.register_entity(product_name, {
hp_max = def.hp_max or 1, hp_max = def.hp_max or 1,
physical = true, physical = true,
weight = def.weight or 5, weight = def.weight or 5,
collistionbox = def.collistionbox or { -0.35, -0.5, -0.35, 0.35, 1.1, 0.35 }, collistionbox = def.collistionbox or { -0.35, -0.5, -0.35, 0.35, 1.1, 0.35 },
visual = "mesh", visual = "mesh",
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = def.mesh or "maidroid.b3d", mesh = def.mesh or "maidroid.b3d",
textures = def.textures or {"maidroid.png"}, textures = def.textures or {"maidroid.png"},
is_visible = true, is_visible = true,
makes_footstep_sound = true, makes_footstep_sound = true,
module = nil, module = nil,
invname = "", invname = "",
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
self.invname = "maidroid"..tostring(gen_inv_serialnumber()) self.invname = "maidroid"..tostring(gen_inv_serialnumber())
local inv = minetest.create_detached_inventory(self.invname, { local inv = minetest.create_detached_inventory(self.invname, {
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
if listname == module_invname then if listname == module_invname then
local module_name = stack:get_name() local module_name = stack:get_name()
local module_def = maidroid.registered_modules[module_name] local module_def = maidroid.registered_modules[module_name]
self.module = module_def self.module = module_def
module_def.initialize(self) module_def.initialize(self)
end end
end, end,
allow_put = function(inv, listname, index, stack, player) allow_put = function(inv, listname, index, stack, player)
local item_name = stack:get_name() local item_name = stack:get_name()
local is_module = maidroid.registered_modules[item_name] local is_module = maidroid.registered_modules[item_name]
if listname == main_invname if listname == main_invname
or (listname == module_invname and is_module) then or (listname == module_invname and is_module) then
return stack:get_count() return stack:get_count()
end end
return 0 return 0
end, end,
on_take = function(inv, listname, index, stack, player) on_take = function(inv, listname, index, stack, player)
if listname == module_invname then if listname == module_invname then
local module_name = stack:get_name() local module_name = stack:get_name()
local module_def = maidroid.registered_modules[module_name] local module_def = maidroid.registered_modules[module_name]
self.module = nil self.module = nil
module_def.finalize(self) module_def.finalize(self)
end end
end, end,
}) })
inv:set_size(main_invname, main_invsize) inv:set_size(main_invname, main_invsize)
inv:set_size(module_invname, module_invsize) inv:set_size(module_invname, module_invsize)
-- process staticdata -- process staticdata
if staticdata ~= "" then if staticdata ~= "" then
local data = minetest.deserialize(staticdata) local data = minetest.deserialize(staticdata)
if data.inv.module ~= "" then if data.inv.module ~= "" then
module_stack = ItemStack(data.inv.module) module_stack = ItemStack(data.inv.module)
module_stack:set_count(1) module_stack:set_count(1)
inv:add_item(module_invname, module_stack) inv:add_item(module_invname, module_stack)
self.module = maidroid.registered_modules[data.inv.module] self.module = maidroid.registered_modules[data.inv.module]
end end
for _, item in ipairs(data.inv.main) do for _, item in ipairs(data.inv.main) do
local itemstack = ItemStack(item.name) local itemstack = ItemStack(item.name)
itemstack:set_count(item.count) itemstack:set_count(item.count)
inv:add_item(main_invname, itemstack) inv:add_item(main_invname, itemstack)
end end
end end
-- initialize module -- initialize module
if self.module then self.module.initialize(self) if self.module then self.module.initialize(self)
else else
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
self.object:setacceleration{x = 0, y = -10, z = 0} self.object:setacceleration{x = 0, y = -10, z = 0}
end end
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
if self.module then self.module.on_step(self, dtime) end if self.module then self.module.on_step(self, dtime) end
end, end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
local formspec = "size[8,9]" local formspec = "size[8,9]"
.."list[detached:"..self.invname..";"..main_invname..";0,0;4,4;]" .."list[detached:"..self.invname..";"..main_invname..";0,0;4,4;]"
.."label[5,0;MODULE]" .."label[5,0;MODULE]"
.."list[detached:"..self.invname..";"..module_invname..";6,0;1,1;]" .."list[detached:"..self.invname..";"..module_invname..";6,0;1,1;]"
.."list[current_player;"..main_invname..";0,5;8,1;]" .."list[current_player;"..main_invname..";0,5;8,1;]"
.."list[current_player;"..main_invname..";0,6.2;8,3;8]" .."list[current_player;"..main_invname..";0,6.2;8,3;8]"
minetest.show_formspec(clicker:get_player_name(), self.invname, formspec) minetest.show_formspec(clicker:get_player_name(), self.invname, formspec)
end, end,
get_staticdata = function(self) get_staticdata = function(self)
local inv = _aux.get_maidroid_inventory(self) local inv = _aux.get_maidroid_inventory(self)
local staticdata = {} local staticdata = {}
staticdata.inv = {} staticdata.inv = {}
local module_name = inv:get_list(module_invname)[1]:get_name() local module_name = inv:get_list(module_invname)[1]:get_name()
staticdata.inv.module = module_name or "" staticdata.inv.module = module_name or ""
staticdata.inv.main = {} staticdata.inv.main = {}
for _, item in ipairs(inv:get_list(main_invname)) do for _, item in ipairs(inv:get_list(main_invname)) do
local count = item:get_count() local count = item:get_count()
local itemname = item:get_name() local itemname = item:get_name()
if count ~= 0 then if count ~= 0 then
local itemdata = { count = count, name = itemname } local itemdata = { count = count, name = itemname }
table.insert(staticdata.inv.main, itemdata) table.insert(staticdata.inv.main, itemdata)
end end
end end
return minetest.serialize(staticdata) return minetest.serialize(staticdata)
end, end,
}) })
-- register spawn egg -- register spawn egg
minetest.register_craftitem(product_name.."_spawn_egg", { minetest.register_craftitem(product_name.."_spawn_egg", {
description = def.description.." Spawn Egg", description = def.description.." Spawn Egg",
inventory_image = def.inventory_image, inventory_image = def.inventory_image,
stack_max = 1, stack_max = 1,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if pointed_thing.above ~= nil then if pointed_thing.above ~= nil then
minetest.add_entity(pointed_thing.above, product_name) minetest.add_entity(pointed_thing.above, product_name)
return itemstack return itemstack
end end
return nil return nil
end end
}) })
end end

View File

@ -4,21 +4,21 @@
------------------------------------------------------------ ------------------------------------------------------------
maidroid.register_maidroid("maidroid:maidroid", { maidroid.register_maidroid("maidroid:maidroid", {
hp_max = 10, hp_max = 10,
description = "Maidroid : Maidroid", description = "Maidroid : Maidroid",
inventory_image = "maidroid_maidroid.png", inventory_image = "maidroid_maidroid.png",
}) })
maidroid.register_maidroid("maidroid:maidroid_mk2", { maidroid.register_maidroid("maidroid:maidroid_mk2", {
hp_max = 10, hp_max = 10,
description = "Maidroid : Maidroid MkII", description = "Maidroid : Maidroid MkII",
textures = {"maidroid_mk2.png"}, textures = {"maidroid_mk2.png"},
inventory_image = "maidroid_maidroid_mk2.png", inventory_image = "maidroid_maidroid_mk2.png",
}) })
maidroid.register_maidroid("maidroid:maidroid_mk3", { maidroid.register_maidroid("maidroid:maidroid_mk3", {
hp_max = 10, hp_max = 10,
description = "Maidroid : Maidroid MkIII", description = "Maidroid : Maidroid MkIII",
textures = {"maidroid_mk3.png"}, textures = {"maidroid_mk3.png"},
inventory_image = "maidroid_maidroid_mk3.png", inventory_image = "maidroid_maidroid_mk3.png",
}) })

View File

@ -9,84 +9,84 @@ local velocity = 3
-- change direction to destination and velocity vector -- change direction to destination and velocity vector
function maidroid.modules._aux.change_dir_to(self, dest) function maidroid.modules._aux.change_dir_to(self, dest)
local pos = self.object:getpos() local pos = self.object:getpos()
local dir = vector.subtract(dest, pos) local dir = vector.subtract(dest, pos)
local vel = vector.multiply(vector.normalize(dir), velocity) local vel = vector.multiply(vector.normalize(dir), velocity)
self.object:setvelocity(vel) self.object:setvelocity(vel)
self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2) self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2)
end end
-- change direction and velocity vector -- change direction and velocity vector
function maidroid.modules._aux.change_dir(self) function maidroid.modules._aux.change_dir(self)
local rnd = function() return math.random(0, 5) * 2 - 5 end local rnd = function() return math.random(0, 5) * 2 - 5 end
local dir = {x = rnd(), y = 0, z = rnd()} local dir = {x = rnd(), y = 0, z = rnd()}
local vel = vector.multiply(vector.normalize(dir), velocity) local vel = vector.multiply(vector.normalize(dir), velocity)
self.object:setvelocity(vel) self.object:setvelocity(vel)
self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2) self.object:setyaw(math.atan2(vel.z, vel.x) + math.pi / 2)
end end
-- get direction vector by yaw -- get direction vector by yaw
function maidroid.modules._aux.get_forward(yaw) function maidroid.modules._aux.get_forward(yaw)
return { x = math.sin(yaw), y = 0.0, z = -math.cos(yaw) } return { x = math.sin(yaw), y = 0.0, z = -math.cos(yaw) }
end end
-- round direction vector -- round direction vector
function maidroid.modules._aux.get_round_forward(forward) function maidroid.modules._aux.get_round_forward(forward)
local rforward = { x = 0, y = 0, z = 0} 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 math.abs((forward.x / (math.abs(forward.x) + math.abs(forward.z)))) > 0.5 then
if forward.x > 0 then rforward.x = 1 if forward.x > 0 then rforward.x = 1
else rforward.x = -1 end else rforward.x = -1 end
end end
if math.abs((forward.z / (math.abs(forward.x) + math.abs(forward.z)))) > 0.5 then if math.abs((forward.z / (math.abs(forward.x) + math.abs(forward.z)))) > 0.5 then
if forward.z > 0 then rforward.z = 1 if forward.z > 0 then rforward.z = 1
else rforward.z = -1 end else rforward.z = -1 end
end end
return rforward return rforward
end end
function maidroid.modules._aux.get_under_pos(vec) function maidroid.modules._aux.get_under_pos(vec)
return { x = vec.x, y = vec.y - 1, z = vec.z } return { x = vec.x, y = vec.y - 1, z = vec.z }
end end
function maidroid.modules._aux.get_upper_pos(vec) function maidroid.modules._aux.get_upper_pos(vec)
return { x = vec.x, y = vec.y + 1, z = vec.z } return { x = vec.x, y = vec.y + 1, z = vec.z }
end end
-- pickup droped items -- pickup droped items
function maidroid.modules._aux.pickup_item(self, radius, target_pred) function maidroid.modules._aux.pickup_item(self, radius, target_pred)
local pos = self.object:getpos() local pos = self.object:getpos()
local pred = target_pred or (function(itemstring) return true end) local pred = target_pred or (function(itemstring) return true end)
local all_objects = minetest.get_objects_inside_radius(pos, radius) local all_objects = minetest.get_objects_inside_radius(pos, radius)
for _, obj in ipairs(all_objects) do for _, obj in ipairs(all_objects) do
if not obj:is_player() and obj:get_luaentity() then if not obj:is_player() and obj:get_luaentity() then
local itemstring = obj:get_luaentity().itemstring local itemstring = obj:get_luaentity().itemstring
if itemstring then if itemstring then
if pred(itemstring) then if pred(itemstring) then
local inv = maidroid._aux.get_maidroid_inventory(self) local inv = maidroid._aux.get_maidroid_inventory(self)
local stack = ItemStack(itemstring) local stack = ItemStack(itemstring)
local leftover = inv:add_item("main", stack) local leftover = inv:add_item("main", stack)
minetest.add_item(obj:getpos(), leftover) minetest.add_item(obj:getpos(), leftover)
obj:get_luaentity().itemstring = "" obj:get_luaentity().itemstring = ""
obj:remove() obj:remove()
end end
end end
end end
end end
end end
-- search surrounding nodes -- search surrounding nodes
function maidroid.modules._aux.search_surrounding(self, lenvec, pred) function maidroid.modules._aux.search_surrounding(self, lenvec, pred)
local pos = vector.round(self.object:getpos()) local pos = vector.round(self.object:getpos())
for xi = -lenvec.x, lenvec.x do for xi = -lenvec.x, lenvec.x do
for yi = -lenvec.y, lenvec.y do for yi = -lenvec.y, lenvec.y do
for zi = -lenvec.z, lenvec.z do for zi = -lenvec.z, lenvec.z do
local p = {x = pos.x + xi, y = pos.y + yi, z = pos.z + zi} local p = {x = pos.x + xi, y = pos.y + yi, z = pos.z + zi}
local node = minetest.get_node(p) local node = minetest.get_node(p)
if pred(self, p, node) then return true, p, node end if pred(self, p, node) then return true, p, node end
end end
end end
end end
return false, nil, nil return false, nil, nil
end end

View File

@ -11,65 +11,65 @@ local view_of_range = 7
local stop_of_range = 2 local stop_of_range = 2
maidroid.register_module("maidroid:chasing_player_module", { maidroid.register_module("maidroid:chasing_player_module", {
description = "Maidroid Module : Chasing Player", description = "Maidroid Module : Chasing Player",
inventory_image = "maidroid_chasing_player_module.png", inventory_image = "maidroid_chasing_player_module.png",
initialize = function(self) initialize = function(self)
self.state = state.idle self.state = state.idle
self.object:setacceleration{x = 0, y = -10, z = 0} self.object:setacceleration{x = 0, y = -10, z = 0}
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
end, end,
finalize = function(self) finalize = function(self)
self.state = nil self.state = nil
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
local all_objects = minetest.get_objects_inside_radius(pos, view_of_range) local all_objects = minetest.get_objects_inside_radius(pos, view_of_range)
local player = nil local player = nil
for _, obj in pairs(all_objects) do for _, obj in pairs(all_objects) do
if obj:is_player() then player = obj; break end if obj:is_player() then player = obj; break end
end end
if not player then if not player then
self.object:set_animation(maidroid.animations.stand, 15, 0) self.object:set_animation(maidroid.animations.stand, 15, 0)
self.state = state.idle self.state = state.idle
return return
end end
local ppos = player:getpos() local ppos = player:getpos()
local dir = vector.subtract(ppos, pos) local dir = vector.subtract(ppos, pos)
local vel = self.object:getvelocity() local vel = self.object:getvelocity()
if (vector.length(dir) < stop_of_range) then if (vector.length(dir) < stop_of_range) then
if self.state == state.chase then if self.state == state.chase then
self.object:set_animation(maidroid.animations.stand, 15, 0) self.object:set_animation(maidroid.animations.stand, 15, 0)
self.state = state.idle self.state = state.idle
self.object:setvelocity({x = 0, y = vel.y, z = 0}) self.object:setvelocity({x = 0, y = vel.y, z = 0})
end end
else else
if self.state == state.idle then if self.state == state.idle then
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.state = state.chase self.state = state.chase
end end
self.object:setvelocity({x = dir.x, y = vel.y, z = dir.z}) self.object:setvelocity({x = dir.x, y = vel.y, z = dir.z})
end end
local yaw = math.atan2(dir.z, dir.x) + math.pi/2 local yaw = math.atan2(dir.z, dir.x) + math.pi/2
self.object:setyaw(yaw) self.object:setyaw(yaw)
-- jump process -- jump process
if vel.y == 0 and self.state == state.chase then if vel.y == 0 and self.state == state.chase then
local rdir = vector.round(dir) local rdir = vector.round(dir)
local front_vec = { x = 0, y = 0, z = 0 } 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 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 if rdir.x > 0 then front_vec.x = 1 else front_vec.x = -1 end
end end
if math.abs((rdir.z / (math.abs(rdir.x) + math.abs(rdir.z)))) > 0.5 then 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 if rdir.z > 0 then front_vec.z = 1 else front_vec.z = -1 end
end end
local front_pos = vector.add(vector.round(pos), front_vec) local front_pos = vector.add(vector.round(pos), front_vec)
if minetest.get_node(front_pos).name ~= "air" then if minetest.get_node(front_pos).name ~= "air" then
self.object:setvelocity({x = dir.x, y = 5, z = dir.z}) self.object:setvelocity({x = dir.x, y = 5, z = dir.z})
end end
end end
end, end,
}) })

View File

@ -4,9 +4,9 @@
------------------------------------------------------------ ------------------------------------------------------------
maidroid.register_module("maidroid:empty_module", { maidroid.register_module("maidroid:empty_module", {
description = "Maidroid Module : Empty Module", description = "Maidroid Module : Empty Module",
inventory_image = "maidroid_empty_module.png", inventory_image = "maidroid_empty_module.png",
initialize = function(self) end, initialize = function(self) end,
finalize = function(self) end, finalize = function(self) end,
on_step = function(self, dtime) end, on_step = function(self, dtime) end,
}) })

View File

@ -6,12 +6,12 @@
local _aux = maidroid.modules._aux local _aux = maidroid.modules._aux
local state = { local state = {
walk = 0, walk = 0,
punch = 1, punch = 1,
plant = 2, plant = 2,
walk_to_plant = 3, walk_to_plant = 3,
walk_to_soil = 4, walk_to_soil = 4,
walk_avoid = 5, walk_avoid = 5,
} }
local max_punch_time = 20 local max_punch_time = 20
local max_plant_time = 15 local max_plant_time = 15
@ -22,188 +22,188 @@ local search_lenvec = {x = 3, y = 0, z = 3}
-- find max size of each plants -- find max size of each plants
local target_plants_list = {} local target_plants_list = {}
minetest.after(0, function() minetest.after(0, function()
local max = {} local max = {}
for name, node in pairs(minetest.registered_nodes) do for name, node in pairs(minetest.registered_nodes) do
if minetest.get_item_group(name, "plant") > 0 then if minetest.get_item_group(name, "plant") > 0 then
local s, i = string.match(name, "(.+)_(%d+)") local s, i = string.match(name, "(.+)_(%d+)")
if (s and i) and (max[s] == nil or max[s] < i) then max[s] = i end if (s and i) and (max[s] == nil or max[s] < i) then max[s] = i end
end end
end end
for s, i in pairs(max) do for s, i in pairs(max) do
table.insert(target_plants_list, s.."_"..i) table.insert(target_plants_list, s.."_"..i)
end end
end) end)
-- check the maidroid has seed items -- check the maidroid has seed items
local function has_seed_item(self) local function has_seed_item(self)
local inv = maidroid._aux.get_maidroid_inventory(self) local inv = maidroid._aux.get_maidroid_inventory(self)
local stacks = inv:get_list("main") local stacks = inv:get_list("main")
for _, stack in ipairs(stacks) do for _, stack in ipairs(stacks) do
local item_name = stack:get_name() local item_name = stack:get_name()
if minetest.get_item_group(item_name, "seed") > 0 then if minetest.get_item_group(item_name, "seed") > 0 then
return true return true
end end
end end
return false return false
end end
-- check can plant plants. -- check can plant plants.
local function can_plant(self, pos) local function can_plant(self, pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local upos = _aux.get_under_pos(pos) local upos = _aux.get_under_pos(pos)
local unode = minetest.get_node(upos) local unode = minetest.get_node(upos)
return node.name == "air" return node.name == "air"
and minetest.get_item_group(unode.name, "wet") > 0 and minetest.get_item_group(unode.name, "wet") > 0
and has_seed_item(self) and has_seed_item(self)
end end
-- check can punch plant -- check can punch plant
local function can_punch(self, pos) local function can_punch(self, pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
return maidroid.util.table_find_value(target_plants_list, node.name) return maidroid.util.table_find_value(target_plants_list, node.name)
end end
-- change state to walk -- change state to walk
local function to_walk(self) local function to_walk(self)
self.state = state.walk self.state = state.walk
self.destination = nil self.destination = nil
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.time_count = 0 self.time_count = 0
_aux.change_dir(self) _aux.change_dir(self)
end end
local function to_walk_avoid(self) local function to_walk_avoid(self)
to_walk(self) to_walk(self)
self.state = state.walk_avoid self.state = state.walk_avoid
end end
maidroid.register_module("maidroid:farming_module", { maidroid.register_module("maidroid:farming_module", {
description = "Maidroid Module : Farming", description = "Maidroid Module : Farming",
inventory_image = "maidroid_farming_module.png", inventory_image = "maidroid_farming_module.png",
initialize = function(self) initialize = function(self)
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.object:setacceleration{x = 0, y = -10, z = 0} self.object:setacceleration{x = 0, y = -10, z = 0}
self.state = state.walk self.state = state.walk
self.preposition = self.object:getpos() self.preposition = self.object:getpos()
self.time_count = 0 self.time_count = 0
self.destination = nil -- for walk_to_* self.destination = nil -- for walk_to_*
_aux.change_dir(self) _aux.change_dir(self)
end, end,
finalize = function(self) finalize = function(self)
self.state = nil self.state = nil
self.preposition = nil self.preposition = nil
self.time_count = nil self.time_count = nil
self.destination = nil self.destination = nil
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
local rpos = vector.round(pos) local rpos = vector.round(pos)
local upos = _aux.get_under_pos(pos) local upos = _aux.get_under_pos(pos)
local yaw = self.object:getyaw() local yaw = self.object:getyaw()
_aux.pickup_item(self, 1.5, function(itemstring) -- pickup droped seed items _aux.pickup_item(self, 1.5, function(itemstring) -- pickup droped seed items
return minetest.get_item_group(itemstring, "seed") > 0 return minetest.get_item_group(itemstring, "seed") > 0
end) end)
if self.state == state.walk then -- searching plants or spaces if self.state == state.walk then -- searching plants or spaces
local b1, dest1 = _aux.search_surrounding(self, search_lenvec, can_plant) local b1, dest1 = _aux.search_surrounding(self, search_lenvec, can_plant)
local b2, dest2 = _aux.search_surrounding(self, search_lenvec, can_punch) local b2, dest2 = _aux.search_surrounding(self, search_lenvec, can_punch)
-- search soil node near -- search soil node near
if b1 then -- to soil if b1 then -- to soil
self.state = state.walk_to_soil self.state = state.walk_to_soil
self.destination = dest1 self.destination = dest1
_aux.change_dir_to(self, dest1) _aux.change_dir_to(self, dest1)
elseif b2 then elseif b2 then
self.state = state.walk_to_plant self.state = state.walk_to_plant
self.destination = dest2 self.destination = dest2
_aux.change_dir_to(self, dest2) _aux.change_dir_to(self, dest2)
elseif pos.x == self.preposition.x or pos.z == self.preposition.z then elseif pos.x == self.preposition.x or pos.z == self.preposition.z then
_aux.change_dir(self) _aux.change_dir(self)
end end
elseif self.state == state.punch then elseif self.state == state.punch then
if self.time_count >= max_punch_time then if self.time_count >= max_punch_time then
if can_punch(self, self.destination) then if can_punch(self, self.destination) then
local destnode = minetest.get_node(self.destination) local destnode = minetest.get_node(self.destination)
minetest.remove_node(self.destination) minetest.remove_node(self.destination)
local inv = minetest.get_inventory{type = "detached", name = self.invname} local inv = minetest.get_inventory{type = "detached", name = self.invname}
local stacks = minetest.get_node_drops(destnode.name) local stacks = minetest.get_node_drops(destnode.name)
for _, stack in ipairs(stacks) do for _, stack in ipairs(stacks) do
local leftover = inv:add_item("main", stack) local leftover = inv:add_item("main", stack)
minetest.add_item(self.destination, leftover) minetest.add_item(self.destination, leftover)
end end
end end
to_walk(self) to_walk(self)
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
elseif self.state == state.plant then elseif self.state == state.plant then
if self.time_count >= max_plant_time then if self.time_count >= max_plant_time then
if can_plant(self, self.destination) then if can_plant(self, self.destination) then
local inv = minetest.get_inventory{type = "detached", name = self.invname} local inv = minetest.get_inventory{type = "detached", name = self.invname}
local stacks = inv:get_list("main") local stacks = inv:get_list("main")
for idx, stack in ipairs(stacks) do for idx, stack in ipairs(stacks) do
local item_name = stack:get_name() local item_name = stack:get_name()
if minetest.get_item_group(item_name, "seed") > 0 then if minetest.get_item_group(item_name, "seed") > 0 then
minetest.add_node(self.destination, {name = item_name, param2 = 1}) minetest.add_node(self.destination, {name = item_name, param2 = 1})
stack:take_item(1) stack:take_item(1)
inv:set_stack("main", idx, stack) inv:set_stack("main", idx, stack)
break break
end end
end end
end end
to_walk(self) to_walk(self)
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
elseif self.state == state.walk_to_soil then elseif self.state == state.walk_to_soil then
if vector.distance(pos, self.destination) < 1.5 then -- to plant state if vector.distance(pos, self.destination) < 1.5 then -- to plant state
local destnode = minetest.get_node(self.destination) local destnode = minetest.get_node(self.destination)
if (can_plant(self, self.destination)) then if (can_plant(self, self.destination)) then
self.state = state.plant self.state = state.plant
self.object:set_animation(maidroid.animations.mine, 15, 0) self.object:set_animation(maidroid.animations.mine, 15, 0)
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
else to_walk(self) end else to_walk(self) end
else else
if pos.x == self.preposition.x or pos.z == self.preposition.z then if pos.x == self.preposition.x or pos.z == self.preposition.z then
to_walk_avoid(self) to_walk_avoid(self)
end end
end end
elseif self.state == state.walk_to_plant then elseif self.state == state.walk_to_plant then
if vector.distance(pos, self.destination) < 1.5 then if vector.distance(pos, self.destination) < 1.5 then
local destnode = minetest.get_node(self.destination) local destnode = minetest.get_node(self.destination)
if maidroid.util.table_find_value(target_plants_list, destnode.name) then if maidroid.util.table_find_value(target_plants_list, destnode.name) then
self.state = state.punch self.state = state.punch
self.object:set_animation(maidroid.animations.mine, 15, 0) self.object:set_animation(maidroid.animations.mine, 15, 0)
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
else to_walk(self) end else to_walk(self) end
else else
if pos.x == self.preposition.x or pos.z == self.preposition.z then if pos.x == self.preposition.x or pos.z == self.preposition.z then
to_walk_avoid(self) to_walk_avoid(self)
end end
end end
elseif self.state == state.walk_avoid then elseif self.state == state.walk_avoid then
if self.time_count > max_avoid_time then if self.time_count > max_avoid_time then
self.state = state.walk self.state = state.walk
self.time_count = 0 self.time_count = 0
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
end end
self.preposition = pos self.preposition = pos
return return
end end
}) })

View File

@ -7,11 +7,11 @@ local util = maidroid.util
local _aux = maidroid.modules._aux local _aux = maidroid.modules._aux
local state = { local state = {
walk = 0, walk = 0,
plant = 1, plant = 1,
punch = 2, punch = 2,
walk_to_tree = 3, walk_to_tree = 3,
walk_avoid = 4, walk_avoid = 4,
} }
local find_lenvec = {x = 3, y = 0, z = 3} local find_lenvec = {x = 3, y = 0, z = 3}
local plant_lenvec = {x = 2, y = 0, z = 2} local plant_lenvec = {x = 2, y = 0, z = 2}
@ -23,170 +23,170 @@ local target_sapling_list = { "default:sapling" }
-- check the maidroid need to start to punch -- check the maidroid need to start to punch
local function check_punch_flag(forward_pos) local function check_punch_flag(forward_pos)
local forward_upper_pos = util.table_shallow_copy(forward_pos) local forward_upper_pos = util.table_shallow_copy(forward_pos)
while true do while true do
local forward_upper_node = minetest.get_node(forward_upper_pos) local forward_upper_node = minetest.get_node(forward_upper_pos)
if util.table_find_value(target_tree_list, forward_upper_node.name) then if util.table_find_value(target_tree_list, forward_upper_node.name) then
return true, forward_upper_pos, forward_upper_node return true, forward_upper_pos, forward_upper_node
elseif forward_upper_node.name ~= "air" then break end elseif forward_upper_node.name ~= "air" then break end
forward_upper_pos.y = forward_upper_pos.y + 1 forward_upper_pos.y = forward_upper_pos.y + 1
end end
return false, nil, nil return false, nil, nil
end end
-- check the maidroid has sapling items -- check the maidroid has sapling items
local function has_sapling_item(self) local function has_sapling_item(self)
local inv = maidroid._aux.get_maidroid_inventory(self) local inv = maidroid._aux.get_maidroid_inventory(self)
local stacks = inv:get_list("main") local stacks = inv:get_list("main")
for _, stack in ipairs(stacks) do for _, stack in ipairs(stacks) do
local item_name = stack:get_name() local item_name = stack:get_name()
if util.table_find_value(target_sapling_list, item_name) then if util.table_find_value(target_sapling_list, item_name) then
return true return true
end end
end end
return false return false
end end
maidroid.register_module("maidroid:lumberjack_module", { maidroid.register_module("maidroid:lumberjack_module", {
description = "Maidroid Module : Lumberjack", description = "Maidroid Module : Lumberjack",
inventory_image = "maidroid_lumberjack_module.png", inventory_image = "maidroid_lumberjack_module.png",
initialize = function(self) initialize = function(self)
self.state = state.walk self.state = state.walk
self.time_count = 0 self.time_count = 0
self.object:setacceleration{x = 0, y = -10, z = 0} self.object:setacceleration{x = 0, y = -10, z = 0}
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.preposition = self.object:getpos() self.preposition = self.object:getpos()
self.destination = nil self.destination = nil
_aux.change_dir(self) _aux.change_dir(self)
end, end,
finalize = function(self) finalize = function(self)
self.state = nil self.state = nil
self.time_count = nil self.time_count = nil
self.preposition = nil self.preposition = nil
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
self.destination = nil self.destination = nil
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
local rpos = vector.round(pos) local rpos = vector.round(pos)
local yaw = self.object:getyaw() local yaw = self.object:getyaw()
local forward = _aux.get_forward(yaw) local forward = _aux.get_forward(yaw)
local rforward = _aux.get_round_forward(forward) local rforward = _aux.get_round_forward(forward)
local forward_pos = vector.add(rpos, rforward) local forward_pos = vector.add(rpos, rforward)
local forward_node = minetest.get_node(forward_pos) local forward_node = minetest.get_node(forward_pos)
local forward_under_pos = _aux.get_under_pos(forward_pos) local forward_under_pos = _aux.get_under_pos(forward_pos)
local forward_under_node = minetest.get_node(forward_under_pos) local forward_under_node = minetest.get_node(forward_under_pos)
if self.state == state.walk then if self.state == state.walk then
local b, dest = _aux.search_surrounding(self, find_lenvec, function(self, pos, node) local b, dest = _aux.search_surrounding(self, find_lenvec, function(self, pos, node)
return util.table_find_value(target_tree_list, node.name) return util.table_find_value(target_tree_list, node.name)
end) end)
if b then -- walk to tree if b then -- walk to tree
self.state = state.walk_to_tree self.state = state.walk_to_tree
self.destination = dest self.destination = dest
_aux.change_dir_to(self, dest) _aux.change_dir_to(self, dest)
-- to plant sapling -- to plant sapling
elseif forward_node.name == "air" elseif forward_node.name == "air"
and minetest.get_item_group(forward_under_node.name, "soil") > 0 and minetest.get_item_group(forward_under_node.name, "soil") > 0
and not _aux.search_surrounding(self, plant_lenvec, function(self, pos, node) -- no tree around and not _aux.search_surrounding(self, plant_lenvec, function(self, pos, node) -- no tree around
return util.table_find_value(target_tree_list, node.name) return util.table_find_value(target_tree_list, node.name)
or util.table_find_value(target_sapling_list, node.name) or util.table_find_value(target_sapling_list, node.name)
end) end)
and has_sapling_item(self) then and has_sapling_item(self) then
self.state = state.plant self.state = state.plant
self.object:set_animation(maidroid.animations.mine, 15, 0) self.object:set_animation(maidroid.animations.mine, 15, 0)
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
-- else continue to walk -- else continue to walk
else else
if pos.x == self.preposition.x or pos.z == self.preposition.z then if pos.x == self.preposition.x or pos.z == self.preposition.z then
_aux.change_dir(self) _aux.change_dir(self)
end end
end end
-- pickup sapling items -- pickup sapling items
_aux.pickup_item(self, 1.5, function(itemstring) _aux.pickup_item(self, 1.5, function(itemstring)
return util.table_find_value(target_sapling_list, itemstring) return util.table_find_value(target_sapling_list, itemstring)
end) end)
elseif self.state == state.punch then elseif self.state == state.punch then
if self.time_count >= max_punch_time then if self.time_count >= max_punch_time then
local punch_flag, forward_upper_pos, forward_upper_node = check_punch_flag(self.destination) local punch_flag, forward_upper_pos, forward_upper_node = check_punch_flag(self.destination)
if punch_flag then if punch_flag then
minetest.remove_node(forward_upper_pos) minetest.remove_node(forward_upper_pos)
local inv = minetest.get_inventory{type = "detached", name = self.invname} local inv = minetest.get_inventory{type = "detached", name = self.invname}
local stacks = minetest.get_node_drops(forward_upper_node.name) local stacks = minetest.get_node_drops(forward_upper_node.name)
for _, stack in ipairs(stacks) do for _, stack in ipairs(stacks) do
local leftover = inv:add_item("main", stack) local leftover = inv:add_item("main", stack)
minetest.add_item(forward_pos, leftover) minetest.add_item(forward_pos, leftover)
end end
end end
if (not forward_upper_pos) or (forward_upper_pos and if (not forward_upper_pos) or (forward_upper_pos and
not check_punch_flag(_aux.get_upper_pos(forward_upper_pos))) then not check_punch_flag(_aux.get_upper_pos(forward_upper_pos))) then
self.state = state.walk self.state = state.walk
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
_aux.change_dir(self) _aux.change_dir(self)
end end
self.time_count = 0 self.time_count = 0
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
elseif self.state == state.plant then elseif self.state == state.plant then
if self.time_count > max_plant_time then if self.time_count > max_plant_time then
if forward_node.name == "air" if forward_node.name == "air"
and minetest.get_item_group(forward_under_node.name, "soil") > 0 then and minetest.get_item_group(forward_under_node.name, "soil") > 0 then
local inv = minetest.get_inventory{type = "detached", name = self.invname} local inv = minetest.get_inventory{type = "detached", name = self.invname}
local stacks = inv:get_list("main") local stacks = inv:get_list("main")
for i, stack in ipairs(stacks) do for i, stack in ipairs(stacks) do
local itemname = stack:get_name() local itemname = stack:get_name()
if util.table_find_value(target_sapling_list, itemname) then if util.table_find_value(target_sapling_list, itemname) then
minetest.add_node(forward_pos, {name = itemname, param2 = 1}) minetest.add_node(forward_pos, {name = itemname, param2 = 1})
stack:take_item(1) stack:take_item(1)
inv:set_stack("main", i, stack) inv:set_stack("main", i, stack)
break break
end end
end end
end end
self.state = state.walk self.state = state.walk
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.time_count = 0 self.time_count = 0
_aux.change_dir(self) _aux.change_dir(self)
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
elseif self.state == state.walk_to_tree then elseif self.state == state.walk_to_tree then
if vector.distance(pos, self.destination) < 1.5 then -- to punch state if vector.distance(pos, self.destination) < 1.5 then -- to punch state
local destnode = minetest.get_node(self.destination) local destnode = minetest.get_node(self.destination)
if (util.table_find_value(target_tree_list, destnode.name)) then if (util.table_find_value(target_tree_list, destnode.name)) then
self.state = state.punch self.state = state.punch
self.object:set_animation(maidroid.animations.mine, 15, 0) self.object:set_animation(maidroid.animations.mine, 15, 0)
self.object:setvelocity{x = 0, y = 0, z = 0} self.object:setvelocity{x = 0, y = 0, z = 0}
else else
self.state = state.walk self.state = state.walk
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.time_count = 0 self.time_count = 0
_aux.change_dir(self) _aux.change_dir(self)
end end
else else
if pos.x == self.preposition.x or pos.z == self.preposition.z then if pos.x == self.preposition.x or pos.z == self.preposition.z then
self.state = state.walk_avoid self.state = state.walk_avoid
self.object:set_animation(maidroid.animations.walk, 15, 0) self.object:set_animation(maidroid.animations.walk, 15, 0)
self.time_count = 0 self.time_count = 0
_aux.change_dir(self) _aux.change_dir(self)
end end
end end
elseif self.state == state.walk_avoid then elseif self.state == state.walk_avoid then
if self.time_count > max_avoid_time then if self.time_count > max_avoid_time then
self.state = state.walk self.state = state.walk
self.time_count = 0 self.time_count = 0
else else
self.time_count = self.time_count + 1 self.time_count = self.time_count + 1
end end
end end
self.preposition = pos self.preposition = pos
end end
}) })

View File

@ -5,65 +5,65 @@
-- maidroids -- maidroids
minetest.register_craft{ minetest.register_craft{
output = "maidroid:maidroid_spawn_egg", output = "maidroid:maidroid_spawn_egg",
recipe = { recipe = {
{"default:diamond", "default:diamond", "default:diamond"}, {"default:diamond", "default:diamond", "default:diamond"},
{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"},
{"default:papyrus", "default:mese_crystal", "default:papyrus"}, {"default:papyrus", "default:mese_crystal", "default:papyrus"},
}, },
} }
minetest.register_craft{ minetest.register_craft{
output = "maidroid:maidroid_mk2_spawn_egg", output = "maidroid:maidroid_mk2_spawn_egg",
recipe = { recipe = {
{"dye:blue", "dye:blue", "dye:blue"}, {"dye:blue", "dye:blue", "dye:blue"},
{"dye:blue", "maidroid:maidroid_spawn_egg", "dye:blue"}, {"dye:blue", "maidroid:maidroid_spawn_egg", "dye:blue"},
{"dye:blue", "dye:blue", "dye:blue"}, {"dye:blue", "dye:blue", "dye:blue"},
}, },
} }
minetest.register_craft{ minetest.register_craft{
output = "maidroid:maidroid_mk3_spawn_egg", output = "maidroid:maidroid_mk3_spawn_egg",
recipe = { recipe = {
{"dye:pink", "dye:pink", "dye:pink"}, {"dye:pink", "dye:pink", "dye:pink"},
{"dye:pink", "maidroid:maidroid_spawn_egg", "dye:pink"}, {"dye:pink", "maidroid:maidroid_spawn_egg", "dye:pink"},
{"dye:pink", "dye:pink", "dye:pink"}, {"dye:pink", "dye:pink", "dye:pink"},
}, },
} }
-- modules -- modules
minetest.register_craft{ minetest.register_craft{
output = "maidroid:empty_module", output = "maidroid:empty_module",
recipe = { recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:obsidian", "default:steel_ingot"}, {"default:steel_ingot", "default:obsidian", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}, },
} }
minetest.register_craft{ minetest.register_craft{
output = "maidroid:chasing_player_module", output = "maidroid:chasing_player_module",
recipe = { recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "maidroid:empty_module", "default:steel_ingot"}, {"default:steel_ingot", "maidroid:empty_module", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}, },
} }
minetest.register_craft{ minetest.register_craft{
output = "maidroid:farming_module", output = "maidroid:farming_module",
recipe = { recipe = {
{"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"}, {"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"},
{"default:gold_ingot", "maidroid:empty_module", "default:gold_ingot"}, {"default:gold_ingot", "maidroid:empty_module", "default:gold_ingot"},
{"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"}, {"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"},
}, },
} }
minetest.register_craft{ minetest.register_craft{
output = "maidroid:lumberjack_module", output = "maidroid:lumberjack_module",
recipe = { recipe = {
{"default:diamond", "default:diamond", "default:diamond"}, {"default:diamond", "default:diamond", "default:diamond"},
{"default:diamond", "maidroid:empty_module", "default:diamond"}, {"default:diamond", "maidroid:empty_module", "default:diamond"},
{"default:diamond", "default:diamond", "default:diamond"}, {"default:diamond", "default:diamond", "default:diamond"},
}, },
} }

View File

@ -7,17 +7,17 @@ maidroid.util = {}
-- check that the table has the value -- check that the table has the value
function maidroid.util.table_find_value(tbl, value) function maidroid.util.table_find_value(tbl, value)
for k, v in ipairs(tbl) do for k, v in ipairs(tbl) do
if v == value then return true, k end if v == value then return true, k end
end end
return false, nil return false, nil
end end
-- table shallow copy -- table shallow copy
function maidroid.util.table_shallow_copy(source) function maidroid.util.table_shallow_copy(source)
local copy = {} local copy = {}
for key, value in pairs(source) do for key, value in pairs(source) do
copy[key] = value copy[key] = value
end end
return copy return copy
end end