Latest stuff

master
Ciaran Gultnieks 2015-04-20 22:32:58 +01:00
parent bcdc792990
commit 70f79c0fc2
11 changed files with 327 additions and 143 deletions

View File

@ -209,6 +209,9 @@ not specified.
#### dig, with pos={x,y,z}
Dig the node at the given position. Must be within range.
#### rightclicknode, with pos={x,y,z}
Right-click the node at the given position. Must be within range.
#### place, with pos={x,y,z} and item=name
Places the given item. Must be in the inventory, and in range.
@ -261,6 +264,10 @@ Gathering remains in effect until it is switched off, or until the person
is re-programmed. Gathering actually happens during "go" and "wait" actions
only (but this includes any action that uses "go" as a subaction).
Both planting and gathering happen in a square +/- 3m around the person.
This means a good farm arrangement is plots that are 7x7, with a (covered)
water source in the middle, where the person stands to plant and harvest.
#### attackplayer
Attack a player. Parameters:

View File

@ -11,7 +11,7 @@ people.actions.attackplayer = function(state)
local player = minetest.get_player_by_name(state.action.name)
if not player then
dbg.v1(state.ent.name.." can't find "..state.action.name.." to follow them")
dbg.v1(state.ent.name.." can't find "..state.action.name.." to attack them")
return true, false
end
@ -24,6 +24,12 @@ people.actions.attackplayer = function(state)
end
if dist < 2 then
-- We're near enough...
if not minetest.line_of_sight(state.pos, targetpos, 0.5) then
dbg.v2(state.ent.name.." can't attack, no line of sight")
return true, false
end
local caps = {
full_punch_interval=2,
groupcaps={
@ -35,6 +41,11 @@ people.actions.attackplayer = function(state)
player:punch(state.ent.object, 5, caps, dir)
state.yaw = vector.get_yaw(state.pos, targetpos)
state.wait = 2
if state.ent.on_done_attack then
state.ent.on_done_attack(state.ent)
end
return false
end

View File

@ -40,29 +40,59 @@ people.actions.dig = function(state)
-- * selecting correct tool
-- * proper drops (e.g. custom handlers in other mods)
local n = minetest.get_node(state.action.pos)
if not minetest.dig_node(state.action.pos) then
dbg.v1(state.ent.name.." failed to dig "..n.name.." at "..minetest.pos_to_string(state.action.pos))
-- Cancel gathering of of the item type if it hits this problem
-- otherwise an infinite repetition will happen.
if #state.gather.items > 0 then
local r = 0
for i, nn in ipairs(state.gather.items) do
if nn == n.name then
r = i
break
if false then
-- old style, do it directly....
if not minetest.dig_node(state.action.pos) then
dbg.v1(state.ent.name.." failed to dig "..n.name.." at "..minetest.pos_to_string(state.action.pos))
-- Cancel gathering of of the item type if it hits this problem
-- otherwise an infinite repetition will happen.
if #state.gather.items > 0 then
local r = 0
for i, nn in ipairs(state.gather.items) do
if nn == n.name then
r = i
break
end
end
if r ~= 0 then
table.remove(state.gather.items, r)
end
end
if r ~= 0 then
table.remove(state.gather.items, r)
end
end
return true, false
end
for _, item in pairs(minetest.get_node_drops(n.name, "")) do
state.ent.inventory:add_item("main", ItemStack(item))
dbg.v1(state.ent.name.." got "..item.." from dig")
return true, false
end
for _, item in pairs(minetest.get_node_drops(n.name, "")) do
state.ent.inventory:add_item("main", ItemStack(item))
dbg.v1(state.ent.name.."got "..item.." from dig")
end
else
-- new style, do it via node_dig
local oldnn = n.name
minetest.node_dig(state.action.pos, n, people.get_fake_player(state.ent))
-- Unfortunately, no indication of success/failure is returned, so...
n = minetest.get_node(state.action.pos)
if n.name == oldnn then
dbg.v1(state.ent.name.." failed to dig "..n.name.." at "..minetest.pos_to_string(state.action.pos).. " - it was still there afterwards")
-- Cancel gathering of of the item type if it hits this problem
-- otherwise an infinite repetition will happen.
if #state.gather.items > 0 then
local r = 0
for i, nn in ipairs(state.gather.items) do
if nn == n.name then
r = i
break
end
end
if r ~= 0 then
table.remove(state.gather.items, r)
end
end
return true, false
end
end
dbg.v1(state.ent.name.." dug "..n.name.." at "..minetest.pos_to_string(state.action.pos))

View File

@ -224,6 +224,22 @@ people.actions.go = function(state)
local colres = state.ent.object:get_last_collision_result()
if colres.collides_xz then
dbg.v3(state.ent.name.." collided at "..minetest.pos_to_string(state.pos).." : "..dump(colres))
-- Maybe we hit a door and can open it?
-- TODO - we ought to do something here to prevent repeated opening
-- attempts if this goes wrong!
if state.ent.can_use_doors then
for _, col in pairs(colres.collisions) do
local colpos = col.node_p
local colnode = minetest.get_node(colpos)
local door = minetest.registered_nodes[colnode.name].groups.door
if door and door ~= 0 then
state.action = {"rightclicknode", pos=colpos, prevaction=state.action}
return false
end
end
end
unwholesome = true
-- We've hit something...
@ -252,8 +268,6 @@ people.actions.go = function(state)
diags = diags .. ":" .. nn
if nn == "ignore" then
unloaded = true
elseif nn == "default:water_flowing" or nn == "default:water_source" or nn == "default:lava_flowing" or nn == "default:lava_source" then
erk = nn
break
end
nd = minetest.registered_nodes[nn]
@ -261,10 +275,24 @@ people.actions.go = function(state)
erk = "mysterious " .. nn
break
end
if nd.walkable and ncount < 6 then
local gg = nd.groups or {}
if gg.water or gg.lava then
erk = nn
break
end
if not nd.walkable then
-- Use 'walkable' to decide if we will bump into, and/or can stand
-- on the node. But with a bit of variation. We ignore doors so we
-- bump into them on purpose!?
local iswalkable = nd.walkable
if iswalkable and state.ent.can_use_doors and nd.groups.door and nd.groups.door ~= 0 then
iswalkable = false
end
if iswalkable and ncount < 6 then
break
end
if not iswalkable then
notwalkable = notwalkable + 1
end
nextpos.y = nextpos.y - 1

View File

@ -2,41 +2,6 @@
local dbg
if moddebug then dbg=moddebug.dbg("people") else dbg={v1=function() end,v2=function() end,v3=function() end} end
local get_fake_player = function(ent)
local defer = function(x)
return (function() return x end)
end
return {
get_inventory_formspec = defer(""),
get_look_dir = defer({x=1,y=0,z=0}),
get_look_pitch = defer(0),
get_look_yaw = defer(0),
get_player_control = defer({jump=false, right=false, left=false, LMB=false, RMB=false, sneak=false, aux1=false, down=false, up=false}),
get_player_control_bits = defer(0),
get_player_name = defer(ent.name),
is_player = defer(true),
set_inventory_formspec = defer(),
getpos = defer(ent.object:getpos()),
get_hp = defer(ent.object:get_hp()),
get_inventory = defer(),
get_wielded_item = defer(),
get_wield_index = defer(),
get_wield_list = defer("main"),
moveto = defer(),
punch = defer(),
remove = defer(),
right_click = defer(),
setpos = defer(),
set_hp = defer(),
set_properties = defer(),
set_wielded_item = defer(),
set_animation = defer(),
set_attach = defer(),
set_detach = defer(),
set_bone_position = defer(),
}
end
people.actions.place = function(state)
@ -84,7 +49,7 @@ people.actions.place = function(state)
above=vector.new(state.action.pos)}
onplace = minetest.registered_items[state.action.item].on_place
if not onplace then onplace = minetest.item_place end
rstack = onplace(ii, get_fake_player(state.ent), pointed_thing)
rstack = onplace(ii, people.get_fake_player(state.ent), pointed_thing)
inv:remove_item("main", ItemStack(state.action.item.." 1"))
dbg.v1(state.ent.name.." placed "..state.action.item.." at "..minetest.pos_to_string(state.action.pos))

View File

@ -0,0 +1,54 @@
local dbg
if moddebug then dbg=moddebug.dbg("people") else dbg={v1=function() end,v2=function() end,v3=function() end} end
people.actions.rightclicknode = function(state)
if not state.action.pos or type(state.action.pos) ~= "table" then
dbg.v1(state.ent.name.." has invalid rightclicknode action")
return true, false
end
local distance = vector.distance(state.pos, state.action.pos)
if distance > 7 then
dbg.v1(state.ent.name.." too far away to click "..minetest.pos_to_string(state.action.pos)..
" from "..minetest.pos_to_string(state.pos).." - "..distance)
return true, false
end
local yaw = vector.get_yaw(state.pos, state.action.pos)
-- Need to be fuzzy about comparing this, because of the
-- lua double/minetest float issue
if math.abs(yaw - state.yaw) > 0.2 then
dbg.v3(state.ent.name.." turning to face click position")
state.action = {"face", yaw=yaw, prevaction=state.action}
return false
end
state.anim = "mine"
if not state.action.digtime then
state.action.digtime = 1
return false
end
state.action.digtime = state.action.digtime - state.dtime
if state.action.digtime > 0 then
return false
end
-- Do it
local n = minetest.get_node(state.action.pos)
local onrc = minetest.registered_nodes[n.name].on_rightclick
if not onrc then
dbg.v3(state.ent.name.." can't right-click "..nn.name..", it has no handler")
return true, false
end
onrc(state.action.pos, n, people.get_fake_player(state.ent), nil, nil)
dbg.v1(state.ent.name.." right-clicked "..n.name.." at "..minetest.pos_to_string(state.action.pos))
return true, true
end

View File

@ -242,7 +242,7 @@ subcmd.setowner = {
return false, person_name.." isn't yours, so so can't do that"
end
end
if not minetest.get_player_by_name(args) then
if not minetest.auth_table[args] then
return false, "No such new owner '"..args.."'"
end
ent.owner = args

View File

@ -1 +1,2 @@
areas?
mod_debug?

View File

@ -83,7 +83,9 @@ people.show_form = function(entity, playername)
if playername == entity.owner then
local prelist = "Custom"
for _, p in ipairs(people.presets) do
prelist = prelist..","..p.name
if not p.priv or minetest.check_player_privs(playername, {server=true}) then
prelist = prelist..","..p.name
end
end
formspec = "size[10,8]"..
"label[0,0;"..message.."]"

View File

@ -28,11 +28,16 @@ dofile(people_modpath .. "/actions/gather.lua")
dofile(people_modpath .. "/actions/stash_and_retrieve.lua")
dofile(people_modpath .. "/actions/attackplayer.lua")
dofile(people_modpath .. "/actions/pickup.lua")
dofile(people_modpath .. "/actions/rightclicknode.lua")
people.footpath_load()
people.presets = {}
for _, p in ipairs({"FollowOwner", "SimpleCommands", "RouteWalker", "FarmHand", "TreeFarmer"}) do
for p, priv in pairs({FollowOwner=false,
SimpleCommands=false,
RouteWalker=false,
FarmHand=true,
TreeFarmer=true}) do
local file = io.open(minetest.get_modpath("people").."/presets/"..p..".lua", "r")
local code
if file then
@ -40,7 +45,7 @@ for _, p in ipairs({"FollowOwner", "SimpleCommands", "RouteWalker", "FarmHand",
else
code = "MISSING"
end
table.insert(people.presets, {code=code, name=p})
table.insert(people.presets, {code=code, name=p, priv=priv})
end
@ -141,6 +146,7 @@ minetest.register_entity("people:person" ,{
mesh = "people_character.x",
textures = {"people_character.png"},
makes_footstep_sound = true,
can_use_doors = true,
owner = "",
code = "@"..people.presets[1].name,
@ -773,3 +779,46 @@ minetest.register_globalstep(function(dtime)
end)
-- Get a fake player object that resembles a real one, for the specified
-- entity. Can be used, in some circumstances, for making API calls that
-- would normally require a real player.
--
-- The player name is actually returned as the owner of the person. This
-- should allow it to, for example, dig with the same permissions as the
-- owner in protected areas, open doors, etc.
people.get_fake_player = function(ent)
local defer = function(x)
return (function() return x end)
end
return {
get_inventory_formspec = defer(""),
get_look_dir = defer({x=1,y=0,z=0}),
get_look_pitch = defer(0),
get_look_yaw = defer(0),
get_player_control = defer({jump=false, right=false, left=false, LMB=false, RMB=false, sneak=false, aux1=false, down=false, up=false}),
get_player_control_bits = defer(0),
get_player_name = defer(ent.owner),
is_player = defer(true),
set_inventory_formspec = defer(),
getpos = defer(ent.object:getpos()),
get_hp = defer(ent.object:get_hp()),
get_inventory = defer(ent.inventory),
get_wielded_item = function() return ItemStack("") end,
get_wield_index = defer(),
get_wield_list = defer("main"),
moveto = defer(),
punch = defer(),
remove = defer(),
right_click = defer(),
setpos = defer(),
set_hp = defer(),
set_properties = defer(),
set_wielded_item = defer(false),
set_animation = defer(),
set_attach = defer(),
set_detach = defer(),
set_bone_position = defer(),
}
end

View File

@ -4,6 +4,121 @@ if event.type == "program" then
mem.failed = false
mem.actions = {
-- *****************
-- Ciaran's Farm
{"go", name="Ciaran's Farm"},
{"wait", time=10},
{"go", pos={x=167,y=11.5,z=316}},
-- These seeds get retrieved from the chest in the barn bef0re
-- harvesting, and the same amount will get put back afterwards.
-- That leaves what doesn't get used to be sent off f0r sale,
-- wh1le still keeping a stock at the farm.
{"retrieve", pos={x=167,y=12,z=314}, items={"farming:seed_wheat 20",
"farming:seed_cotton 20",
"farming_plus:carrot_seed 20",
"farming_plus:tomato_seed 20",
"farming_plus:orange_seed 20",
"farming_plus:potato_seed 20",
"farming_plus:rhubarb_seed 20",
"farming_plus:strawberry_seed 20"}},
{"go", name="Ciaran's Farm"},
-- Row 1
{"go", pos={x=178, y=11.5, z=322}},
{"gather", nodes={"farming:weed", "farming:wheat_8"}, plant="farming:seed_wheat"},
{"wait", time=5},
{"gather"},
{"go", pos={x=178, y=11.5, z=330}},
{"gather", nodes={"farming:weed", "farming:wheat_8"}, plant="farming:seed_wheat"},
{"wait", time=5},
{"gather"},
{"go", pos={x=178, y=11.5, z=338}},
{"gather", nodes={"farming:weed", "farming_plus:potato"}, plant="farming_plus:potato_seed"},
{"wait", time=5},
{"gather"},
{"go", pos={x=178, y=11.5, z=346}},
{"gather", nodes={"farming:weed", "farming:cotton_8"}, plant="farming:seed_cotton"},
{"wait", time=5},
{"gather"},
-- Row 2, back the other way
{"go", pos={x=186, y=11.5, z=346}},
{"gather", nodes={"farming:weed", "farming:cotton_8"}, plant="farming:seed_cotton"},
{"wait", time=5},
{"gather"},
{"go", pos={x=186, y=11.5, z=338}},
{"gather", nodes={"farming:weed", "farming_plus:potato"}, plant="farming_plus:potato_seed"},
{"wait", time=5},
{"gather"},
{"go", pos={x=186, y=11.5, z=330}},
{"gather", nodes={"farming:weed", "farming_plus:carrot"}, plant="farming_plus:carrot_seed"},
{"wait", time=5},
{"gather"},
{"go", pos={x=186, y=11.5, z=322}},
{"gather", nodes={"farming:weed", "farming_plus:rhubarb"}, plant="farming_plus:rhubarb_seed"},
{"wait", time=5},
{"gather"},
-- Row 3
{"go", pos={x=194, y=11.5, z=322}},
{"gather", nodes={"farming:weed", "farming_plus:tomato"}, plant="farming_plus:tomato_seed"},
{"wait", time=5},
{"gather"},
{"go", pos={x=194, y=11.5, z=330}},
{"gather", nodes={"farming:weed", "farming_plus:strawberry"}, plant="farming_plus:strawberry_seed"},
{"wait", time=5},
{"gather"},
{"go", pos={x=194, y=11.5, z=338}},
{"gather", nodes={"farming:weed", "farming_plus:orange"}, plant="farming_plus:orange_seed"},
{"wait", time=5},
{"gather"},
-- Finished. Save seed stock...
{"go", name="Ciaran's Farm"},
{"wait", time=10},
{"go", pos={x=167,y=11.5,z=316}},
{"stash", pos={x=167,y=12,z=314},
items={"farming:seed_wheat 20",
"farming:seed_cotton 20",
"farming_plus:carrot_seed 20",
"farming_plus:tomato_seed 20",
"farming_plus:potato_seed 20",
"farming_plus:orange_seed 20",
"farming_plus:rhubarb_seed 20",
"farming_plus:strawberry_seed 20"}},
-- Load up items...
{"go", name="Ciaran's Farm"},
{"go", pos={x=174, y=11.5, z=319}},
{"go", pos={x=174, y=11.5, z=341}},
{"stash", dest="default:chest", items={"*farming:weed", "*farming:cotton",
"*farming:wheat", "*farming_plus:carrot_item", "*farming:seed_wheat",
"*farming_plus:rhubarb_item",
"*farming_plus:carrot_seed", "*farming:seed_cotton",
"*farming_plus:tomato_seed", "*farming_plus:tomato_item",
"*farming_plus:rhubarb_seed", "*farming_plus:orange_seed",
"*farming_plus:potato_seed", "*farming_plus:potato_item",
"*farming_plus:orange_item",
"*farming_plus:strawberry_item", "*farming_plus:strawberry_seed"}},
{"go", pos={x=174, y=11.5, z=319}},
-- *****************
-- Tree Farm
{"go", name="Jeiffel Tree Farm"},
@ -74,7 +189,7 @@ if event.type == "program" then
-- *****************
-- Get some paprus on the way
-- Get some papyrus on the way
{"go", name="Sugar Station Entrance"},
{"gather", topnodes="default:papyrus"},
{"go", name="Industrial Corner"},
@ -87,84 +202,6 @@ if event.type == "program" then
{"go", pos={x=153, y=4.5, z=203}},
{"go", name="Industrial Estate"},
-- *****************
-- Ciaran's Farm
{"go", name="Ciaran's Farm"},
{"wait", time=10},
{"go", pos={x=167,y=11.5,z=316}},
-- These seeds get retrieved from the chest in the barn bef0re
-- harvesting, and the same amount will get put back afterwards.
-- That leaves what doesn't get used to be sent off f0r sale,
-- wh1le still keeping a stock at the farm.
{"retrieve", pos={x=167,y=12,z=314}, items={"farming:seed_wheat 20",
"farming:seed_cotton 20",
"farming_plus:carrot_seed 20",
"farming_plus:tomato_seed 20",
"farming_plus:potato_seed 20",
"farming_plus:strawberry_seed 20"}},
{"go", name="Ciaran's Farm"},
{"go", pos={x=174, y=11.5, z=319}},
{"gather", nodes={"farming:weed", "farming:wheat_8"}, plant="farming:seed_wheat"},
{"go", pos={x=174, y=11.5, z=346}},
{"go", pos={x=178, y=11.5, z=346}},
{"go", pos={x=178, y=11.5, z=319}},
{"go", pos={x=182, y=11.5, z=319}},
{"gather", nodes={"farming:weed", "farming_plus:potato"}, plant="farming_plus:potato_seed"},
{"go", pos={x=182, y=11.5, z=346}},
{"wait", time=5},
{"gather"},
{"go", pos={x=191, y=11.5, z=347}},
{"gather", nodes={"farming:weed", "farming:cotton_8"}, plant="farming:seed_cotton"},
{"go", pos={x=191, y=11.5, z=341}},
{"wait", time=5},
{"gather"},
{"go", pos={x=191, y=11.5, z=332}},
{"gather", nodes={"farming:weed", "farming_plus:carrot"}, plant="farming_plus:carrot_seed"},
{"go", pos={x=191, y=11.5, z=330}},
{"wait", time=5},
{"gather"},
{"go", pos={x=191, y=11.5, z=323}},
{"gather", nodes={"farming:weed", "farming_plus:strawberry"}, plant="farming_plus:strawberry_seed"},
{"go", pos={x=191, y=11.5, z=321}},
{"wait", time=5},
{"gather"},
{"go", pos={x=199, y=11.5, z=321}},
{"gather", nodes={"farming:weed", "farming_plus:tomato"}, plant="farming_plus:tomato_seed"},
{"go", pos={x=199, y=11.5, z=323}},
{"wait", time=5},
{"gather"},
{"go", name="Ciaran's Farm"},
{"wait", time=10},
{"go", pos={x=167,y=11.5,z=316}},
{"stash", pos={x=167,y=12,z=314},
items={"farming:seed_wheat 20",
"farming:seed_cotton 20",
"farming_plus:carrot_seed 20",
"farming_plus:tomato_seed 20",
"farming_plus:potato_seed 20",
"farming_plus:strawberry_seed 20"}},
{"go", name="Ciaran's Farm"},
{"go", pos={x=174, y=11.5, z=319}},
{"go", pos={x=174, y=11.5, z=341}},
{"stash", dest="default:chest", items={"*farming:weed", "*farming:cotton",
"*farming:wheat", "*farming_plus:carrot_item", "*farming:seed_wheat",
"*farming_plus:carrot_seed", "*farming:seed_cotton",
"*farming_plus:tomato_seed", "*farming_plus:tomato_item",
"*farming_plus:potato_seed", "*farming_plus:potato_item",
"*farming_plus:strawberry_item", "*farming_plus:strawberry_seed"}},
{"go", pos={x=174, y=11.5, z=319}},
-- *****************
-- A bit of random wandering f0r test purposes
{"go", name="Building Supplies Shop"},