More latest stuff
parent
70f79c0fc2
commit
cb29cd13d7
51
README.md
51
README.md
|
@ -80,6 +80,8 @@ In addition:
|
|||
|
||||
* `log(msg)` - logs a v1 debug message
|
||||
* `mem` - the person's memory - see under Persistence
|
||||
* `carrying(item)` - returns the number of a particluar item the person is
|
||||
carrying - e.g. carrying("default:cobble") might return 0, 10, 99 or 198.
|
||||
|
||||
### Persistence
|
||||
|
||||
|
@ -128,6 +130,10 @@ This happens when the person has no current action (see the Actions section).
|
|||
The handler should select a new action, by setting the 'action' variable. If
|
||||
it fails to do so, the person will do an automatic wait.
|
||||
|
||||
### actfail
|
||||
|
||||
This happens when an action fails.
|
||||
|
||||
### tell
|
||||
|
||||
This happens when a player (who must be the owner, current) sends a message
|
||||
|
@ -246,17 +252,38 @@ Each item in the list can be:
|
|||
* Item name preceded by an asterisk (e.g. "\*default:cobble") , to get all
|
||||
of that kind of item out
|
||||
|
||||
#### sell
|
||||
|
||||
* Required parameter: item="itemstring"
|
||||
|
||||
Need to be standing within range of a shop (barrel mod) that buys the item
|
||||
in question.
|
||||
|
||||
The entire amount of the item carried will be sold, assuming the shop can
|
||||
afford to buy it all.
|
||||
|
||||
#### buy
|
||||
|
||||
* Required parameter: item="itemstring"
|
||||
* Required parameter: num=amount
|
||||
|
||||
Need to be standing within range of a shop (barrel mod) that sells the item
|
||||
in question, and have enough money. If the person doesn't have enough money
|
||||
to buy the amount specified, a lesser amount may be bought instead.
|
||||
|
||||
#### gather
|
||||
Changes current gathering settings.
|
||||
|
||||
All parameters are optional:
|
||||
|
||||
* `nodes = {}` - list of nodes to dig
|
||||
* `topnodes = {}` - list of nodes to dig only if there is a) air above,
|
||||
and b) the same node below - think of harvesting cactus/papyrus while
|
||||
still allowing them to grow back!
|
||||
* `items = {}` - list of items to pick up
|
||||
* `plant = ""` - seed to plant
|
||||
* `nodes = {}` - list of nodes to dig
|
||||
* `topnodes = {}` - list of nodes to dig only if there is a) air above,
|
||||
and b) the same node below - think of harvesting
|
||||
cactus/papyrus while still allowing them to grow back!
|
||||
* `items = {}` - list of items to pick up
|
||||
* `plant = nil - seed to plant
|
||||
* animal = nil - species of animal to harvest from
|
||||
* animal_wield = nil - item to wield when harvesting
|
||||
|
||||
So calling with no parameters at all turns off gathering.
|
||||
|
||||
|
@ -278,11 +305,21 @@ The action will cancel when the player is out of range.
|
|||
|
||||
#### pickup
|
||||
|
||||
Picks up an item. Paramaters:
|
||||
Picks up an item. Parameters:
|
||||
|
||||
* `pos = {x,y,z}` - position of the item (required)
|
||||
* `item = "name"` - name of item, e.g. "default:dirt"
|
||||
|
||||
#### harvest
|
||||
|
||||
Harvest from an animal from the animals mod. Parameters:
|
||||
|
||||
* name = "name" - the name of the animal (e.g. "cow 1452")
|
||||
|
||||
The correct item should already be wielded. This is normally used in
|
||||
conjunction with gathering, in which case the wielding is already
|
||||
handled.
|
||||
|
||||
#### step
|
||||
Allow's the person's lua code to handle on_step itself. It will receive
|
||||
"step" events (with dtime) and should reset the action when it no longer
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
|
||||
local dbg
|
||||
if moddebug then dbg=moddebug.dbg("people") else dbg={v1=function() end,v2=function() end,v3=function() end} end
|
||||
|
||||
-- Find a shop in range of the given position that's dealing in the
|
||||
-- item specified. If 'buy' is true, we want to buy, otherwise we
|
||||
-- want to sell. Returns shopinfo. (or nil)
|
||||
local function near_shop(pos, item, buy)
|
||||
local range = {x=4, y=2, z=4}
|
||||
local minp = vector.subtract(pos, range)
|
||||
local maxp = vector.add(pos, range)
|
||||
local shops = minetest.find_nodes_in_area(minp, maxp, {"barrel:shop_barrel"})
|
||||
for _, p in pairs(shops) do
|
||||
local shopinfo = barrel.get_shopinfo(p)
|
||||
if shopinfo and shopinfo.item == item then
|
||||
if buy then
|
||||
if shopinfo.saleunit > 0 and
|
||||
shopinfo.price > 0 and
|
||||
shopinfo.stock >= shopinfo.saleunit then
|
||||
return shopinfo
|
||||
end
|
||||
else
|
||||
if shopinfo.saleunit > 0 and
|
||||
shopinfo.buyprice > 0 then
|
||||
return shopinfo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
local function move_all(srcinv, srclist, destinv, destlist, item)
|
||||
local moved_all = true
|
||||
local moved_num = 0
|
||||
for i=1,srcinv:get_size(srclist) do
|
||||
local stk = srcinv:get_stack(srclist, i)
|
||||
if not item or stk:get_name() == item then
|
||||
if destinv:room_for_item(destlist, stk) then
|
||||
moved_num = moved_num + stk:get_count()
|
||||
srcinv:set_stack(srclist, i, nil)
|
||||
destinv:add_item(destlist, stk)
|
||||
else
|
||||
moved_all = false
|
||||
end
|
||||
end
|
||||
end
|
||||
return moved_all, moved_num
|
||||
end
|
||||
|
||||
|
||||
people.actions.buy = function(state)
|
||||
if not (state.action.item or state.action.num) then
|
||||
dbg.v1(state.ent.name.." has invalid buy action")
|
||||
return true, false
|
||||
end
|
||||
|
||||
local shopinfo = near_shop(state.pos, state.action.item, true)
|
||||
if not shopinfo then
|
||||
dbg.v1(state.ent.name.." is not near an appropriate shop")
|
||||
return true, false
|
||||
end
|
||||
|
||||
local yaw = vector.get_yaw(state.pos, shopinfo.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 shop")
|
||||
state.action = {"face", yaw=yaw, prevaction=state.action}
|
||||
return false
|
||||
end
|
||||
|
||||
local shopinv = shopinfo.meta:get_inventory()
|
||||
local repeats = math.ceil(state.action.num / shopinfo.saleunit)
|
||||
local cashneeded = repeats * shopinfo.price
|
||||
|
||||
if not currency.remove_from_inv(state.ent.inventory, "main", cashneeded) then
|
||||
dbg.v1(state.ent.name.." doesn't have enough money to buy")
|
||||
return true, false
|
||||
end
|
||||
-- TODO - the following just assumes there's room for it - really need
|
||||
-- to check and roll back, as we do for getting money
|
||||
currency.put_to_inv(shopinv, "exchange", cashneeded)
|
||||
|
||||
while repeats > 0 do
|
||||
if not barrel.do_buy(shopinfo.pos) then break end
|
||||
repeats = repeats - 1
|
||||
end
|
||||
|
||||
if not move_all(shopinv, "exchange", state.ent.inventory, "main", nil) then
|
||||
dbg.v1(state.ent.name.." couldn't retrieve everything from shop inventory")
|
||||
end
|
||||
|
||||
dbg.v1(state.ent.name.." finished buy action")
|
||||
return true, true
|
||||
end
|
||||
|
||||
people.actions.sell = function(state)
|
||||
if not (state.action.item) then
|
||||
dbg.v1(state.ent.name.." has invalid sell action")
|
||||
return true, false
|
||||
end
|
||||
|
||||
local shopinfo = near_shop(state.pos, state.action.item, false)
|
||||
if not shopinfo then
|
||||
dbg.v1(state.ent.name.." is not near an appropriate shop")
|
||||
return true, false
|
||||
end
|
||||
|
||||
local yaw = vector.get_yaw(state.pos, shopinfo.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 shop")
|
||||
state.action = {"face", yaw=yaw, prevaction=state.action}
|
||||
return false
|
||||
end
|
||||
|
||||
local shopinv = shopinfo.meta:get_inventory()
|
||||
local moved_all, num = move_all(state.ent.inventory, "main",
|
||||
shopinv, "exchange", state.action.item)
|
||||
if num == 0 then
|
||||
dbg.v1(state.ent.name.." failed to put any "..state.action.item.." for sale into the shop")
|
||||
return true, false
|
||||
end
|
||||
local repeats = math.floor(num / shopinfo.saleunit)
|
||||
|
||||
while repeats > 0 do
|
||||
if not barrel.do_sell(shopinfo.pos) then break end
|
||||
repeats = repeats - 1
|
||||
end
|
||||
|
||||
if not move_all(shopinv, "exchange", state.ent.inventory, "main") then
|
||||
dbg.v1(state.ent.name.." couldn't retrieve everything from shop inventory")
|
||||
end
|
||||
|
||||
dbg.v1(state.ent.name.." finished sell action")
|
||||
return true, true
|
||||
end
|
||||
|
|
@ -5,6 +5,8 @@ people.actions.gather = function(state)
|
|||
state.gather.topnodes = state.action.topnodes or {}
|
||||
state.gather.items = state.action.items or {}
|
||||
state.gather.plant = state.action.plant
|
||||
state.gather.animal = state.action.animal
|
||||
state.gather.animal_wield = state.action.animal_wield
|
||||
return true, true
|
||||
end
|
||||
|
||||
|
|
|
@ -233,7 +233,8 @@ people.actions.go = function(state)
|
|||
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
|
||||
local gate = minetest.registered_nodes[colnode.name].groups.gate
|
||||
if (door and door ~= 0) or (gate and gate ~= 0) then
|
||||
state.action = {"rightclicknode", pos=colpos, prevaction=state.action}
|
||||
return false
|
||||
end
|
||||
|
@ -285,7 +286,9 @@ people.actions.go = function(state)
|
|||
-- 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
|
||||
if iswalkable and state.ent.can_use_doors and (
|
||||
(nd.groups.door and nd.groups.door ~= 0) or
|
||||
(nd.groups.gate and nd.groups.gate ~= 0)) then
|
||||
iswalkable = false
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
local dbg
|
||||
if moddebug then dbg=moddebug.dbg("people") else dbg={v1=function() end,v2=function() end,v3=function() end} end
|
||||
|
||||
people.actions.harvest = function(state)
|
||||
if not state.action.name or type(state.action.name) ~= "string" then
|
||||
dbg.v1(state.ent.name.." has invalid harvest action")
|
||||
return true, false
|
||||
end
|
||||
|
||||
local hitit = nil
|
||||
local objects = minetest.get_objects_inside_radius(state.pos, 6)
|
||||
for k, obj in ipairs(objects) do
|
||||
if not obj:is_player() then
|
||||
local ent = obj:get_luaentity()
|
||||
if ent and ent.name == state.action.name then
|
||||
hitit = ent
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not hitit then
|
||||
dbg.v1(state.ent.name.." can't find "..state.action.name)
|
||||
return true, false
|
||||
end
|
||||
|
||||
local yaw = vector.get_yaw(state.pos, hitit.object:getpos())
|
||||
-- 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 pickup position")
|
||||
state.action = {"face", yaw=yaw, prevaction=state.action}
|
||||
return false
|
||||
end
|
||||
|
||||
state.anim = "mine"
|
||||
|
||||
if not state.action.harvesttime then
|
||||
state.action.harvesttime = 1
|
||||
return false
|
||||
end
|
||||
|
||||
state.action.harvesttime = state.action.harvesttime - state.dtime
|
||||
if state.action.harvesttime > 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
local spinfo = animals.species[hitit.species]
|
||||
if not spinfo.is_harvestable or not spinfo.is_harvestable(hitit) then
|
||||
dbg.v1(state.ent.name.." can't harvest from "..state.action.name)
|
||||
return true, false
|
||||
end
|
||||
|
||||
-- Actually do it, if it's still there
|
||||
spinfo.on_harvest(hitit, people.get_fake_player(state.ent))
|
||||
dbg.v1(state.ent.name.." harvested from "..state.action.name)
|
||||
return true, false
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ people.actions.place = function(state)
|
|||
|
||||
local distance = vector.distance(state.pos, state.action.pos)
|
||||
if distance > 5 then
|
||||
dbg.v1(state.ent.name.." too far away to place "..minetest.pos_to_string(foundpos))
|
||||
dbg.v1(state.ent.name.." too far away to place - distance is "..distance)
|
||||
return true, false
|
||||
end
|
||||
|
||||
|
|
|
@ -209,6 +209,9 @@ subcmd.track = {
|
|||
local person, person_name
|
||||
person_name, person, args = get_person(args)
|
||||
if not person then
|
||||
if args then
|
||||
return false, "No such person as "..person_name
|
||||
end
|
||||
if not people.hud_show_by_player[playername] then
|
||||
return false, "No person was being tracked"
|
||||
end
|
||||
|
|
13
footpath.lua
13
footpath.lua
|
@ -275,9 +275,20 @@ people.footpath_findnext = function(curpos, lastpos, samedironly)
|
|||
--dbg.v3("footpath_findnext found (snow-covered) "..minetest.pos_to_string(npos))
|
||||
return npos
|
||||
end
|
||||
|
||||
-- Otherwise, so long as there's nothing walkable above the
|
||||
-- node it should be a valid footpath node...
|
||||
if not minetest.registered_nodes[n.name].walkable then
|
||||
-- TODO - allowing doors/gates here, as we do elsewhere, but
|
||||
-- really we need to know if the entity can use doors!
|
||||
local nd = minetest.registered_nodes[n.name]
|
||||
local iswalkable = nd.walkable
|
||||
if iswalkable and (
|
||||
(nd.groups.door and nd.groups.door ~= 0) or
|
||||
(nd.groups.gate and nd.groups.gate ~= 0)) then
|
||||
iswalkable = false
|
||||
end
|
||||
|
||||
if not iswalkable then
|
||||
--dbg.v3("footpath_findnext found "..minetest.pos_to_string(npos))
|
||||
return npos
|
||||
end
|
||||
|
|
89
init.lua
89
init.lua
|
@ -14,7 +14,8 @@ dofile(people_modpath .. "/footpath.lua")
|
|||
|
||||
-- Contains all action handlers. Each action handler takes a 'state' table as
|
||||
-- a parameter, and returns true if the current action is complete, false
|
||||
-- otherwise.
|
||||
-- otherwise. When complete, a second boolean is also returned which says
|
||||
-- whether the action completed succesfully, or failed due to an error.
|
||||
people.actions = {}
|
||||
dofile(people_modpath .. "/actions/step.lua")
|
||||
dofile(people_modpath .. "/actions/face.lua")
|
||||
|
@ -26,9 +27,11 @@ dofile(people_modpath .. "/actions/dig.lua")
|
|||
dofile(people_modpath .. "/actions/place.lua")
|
||||
dofile(people_modpath .. "/actions/gather.lua")
|
||||
dofile(people_modpath .. "/actions/stash_and_retrieve.lua")
|
||||
dofile(people_modpath .. "/actions/buy_and_sell.lua")
|
||||
dofile(people_modpath .. "/actions/attackplayer.lua")
|
||||
dofile(people_modpath .. "/actions/pickup.lua")
|
||||
dofile(people_modpath .. "/actions/rightclicknode.lua")
|
||||
dofile(people_modpath .. "/actions/harvest.lua")
|
||||
|
||||
people.footpath_load()
|
||||
|
||||
|
@ -37,6 +40,7 @@ for p, priv in pairs({FollowOwner=false,
|
|||
SimpleCommands=false,
|
||||
RouteWalker=false,
|
||||
FarmHand=true,
|
||||
CowTest=true,
|
||||
TreeFarmer=true}) do
|
||||
local file = io.open(minetest.get_modpath("people").."/presets/"..p..".lua", "r")
|
||||
local code
|
||||
|
@ -169,10 +173,12 @@ minetest.register_entity("people:person" ,{
|
|||
-- picking up of items, which happens in parallel with any other action.
|
||||
--
|
||||
self.gather = {
|
||||
nodes = {}, -- list of nodes to dig up
|
||||
topnodes = {}, -- list of topnodes to dig
|
||||
items = {}, -- list of items to pick up
|
||||
plant = nil, -- name of seed to plant, or nil
|
||||
nodes = {}, -- list of nodes to dig up
|
||||
topnodes = {}, -- list of topnodes to dig
|
||||
items = {}, -- list of items to pick up
|
||||
plant = nil, -- name of seed to plant, or nil
|
||||
animal = nil, -- name of animal to gather from
|
||||
animal_wield = nil, -- when animal set, the item to wield
|
||||
}
|
||||
self.name = "<new person>"
|
||||
|
||||
|
@ -341,7 +347,7 @@ minetest.register_entity("people:person" ,{
|
|||
self.action = {"wait", time=120}
|
||||
dbg.v2(self.name.." failed to choose action - setting wait, at "..minetest.pos_to_string(pos))
|
||||
else
|
||||
dbg.v1(self.name.." set new action: "..dump(self.action))
|
||||
dbg.v1(self.name.." set new action: "..minetest.serialize(self.action))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -354,7 +360,7 @@ minetest.register_entity("people:person" ,{
|
|||
self.action[1] == "follow" or
|
||||
self.action[1] == "wait") and
|
||||
(#self.gather.items + #self.gather.nodes + #self.gather.topnodes > 0 or
|
||||
self.gather.plant) then
|
||||
self.gather.plant or self.gather.animal) then
|
||||
local dist = 99
|
||||
if self.gather.lastpos then
|
||||
dist = vector.distance(pos, self.gather.lastpos)
|
||||
|
@ -364,7 +370,7 @@ minetest.register_entity("people:person" ,{
|
|||
local done = false
|
||||
|
||||
if #self.gather.nodes > 0 then
|
||||
dbg.v2(self.name.." looking for "..dump(self.gather.nodes).." near "..minetest.pos_to_string(pos))
|
||||
dbg.v2(self.name.." looking for "..minetest.serialize(self.gather.nodes).." near "..minetest.pos_to_string(pos))
|
||||
local foundpos = minetest.find_node_near(
|
||||
vector.add(vector.round(pos), {x=0,y=1,z=0}),
|
||||
3, self.gather.nodes)
|
||||
|
@ -376,7 +382,7 @@ minetest.register_entity("people:person" ,{
|
|||
end
|
||||
end
|
||||
if not done and #self.gather.topnodes > 0 then
|
||||
dbg.v2(self.name.." looking for topnodes "..dump(self.gather.topnodes).." near "..minetest.pos_to_string(pos))
|
||||
dbg.v2(self.name.." looking for topnodes "..minetest.serialize(self.gather.topnodes).." near "..minetest.pos_to_string(pos))
|
||||
local minp = vector.add(pos, {x=-3,y=-3,z=-3})
|
||||
local maxp = vector.add(pos, {x=3, y=3, z=3})
|
||||
local pp = minetest.find_nodes_in_area(minp, maxp, self.gather.topnodes)
|
||||
|
@ -394,7 +400,7 @@ minetest.register_entity("people:person" ,{
|
|||
end
|
||||
end
|
||||
if not done and #self.gather.items > 0 then
|
||||
dbg.v2(self.name.." looking for items "..dump(self.gather.items).." near "..minetest.pos_to_string(pos))
|
||||
dbg.v2(self.name.." looking for items "..minetest.serialize(self.gather.items).." near "..minetest.pos_to_string(pos))
|
||||
local objects = minetest.get_objects_inside_radius(
|
||||
vector.add(vector.round(pos), {x=0,y=1,z=0}), 6)
|
||||
for _, obj in ipairs(objects) do
|
||||
|
@ -443,6 +449,41 @@ minetest.register_entity("people:person" ,{
|
|||
end
|
||||
end
|
||||
|
||||
if not done and animals and (self.gather.animal and self.gather.animal_wield) then
|
||||
if self.inventory:contains_item("main", ItemStack(self.gather.animal_wield)) then
|
||||
self.wielded = self.gather.animal_wield
|
||||
|
||||
local spinfo = animals.species[self.gather.animal]
|
||||
if not spinfo then
|
||||
dbg.v1(self.name.." trying to harvest unknown species "..self.gather.animal)
|
||||
self.gather.animal = nil
|
||||
self.gather.animal_wield = nil
|
||||
else
|
||||
local hitit = nil
|
||||
local objects = minetest.get_objects_inside_radius(pos, 5)
|
||||
for k, obj in ipairs(objects) do
|
||||
if not obj:is_player() then
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
dbg.v3(self.name.." examining "..(ent.name or "<noname>"))
|
||||
if ent.species == self.gather.animal then
|
||||
if spinfo.is_harvestable and spinfo.is_harvestable(ent) then
|
||||
hitit = ent
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if hitit then
|
||||
dbg.v1(self.name.." decided to harvest "..hitit.name)
|
||||
self.action = {"harvest", name=hitit.name, prevaction=self.action}
|
||||
done = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not done then
|
||||
-- We didn't find anything to do here, so we can move on
|
||||
self.gather.lastpos = pos
|
||||
|
@ -501,14 +542,14 @@ minetest.register_entity("people:person" ,{
|
|||
action_done, action_success = handler(state)
|
||||
-- Because state.action can be replaced...
|
||||
if state.action ~= self.action then
|
||||
dbg.v3(state.ent.name.." action handler replaced action with "..dump(state.action))
|
||||
dbg.v3(state.ent.name.." action handler replaced action with "..minetest.serialize(state.action))
|
||||
self.action = state.action
|
||||
end
|
||||
if state.gather ~= self.gather then
|
||||
self.gather = state.gather
|
||||
end
|
||||
else
|
||||
dbg.v1(state.ent.name.." has unknown action: "..dump(self.action))
|
||||
dbg.v1(state.ent.name.." has unknown action: "..minetest.serialize(self.action))
|
||||
self.action = nil
|
||||
end
|
||||
|
||||
|
@ -661,7 +702,7 @@ end
|
|||
|
||||
people.exec_event = function(ent, event)
|
||||
|
||||
dbg.v3(ent.name.." exec event "..dump(event))
|
||||
dbg.v3(ent.name.." exec event "..minetest.serialize(event))
|
||||
|
||||
local code = ent.code
|
||||
if string.sub(code, 1, 1) == "@" then
|
||||
|
@ -678,6 +719,21 @@ people.exec_event = function(ent, event)
|
|||
env.action = ent.action
|
||||
env.gather = ent.gather
|
||||
env.mem = ent.memory
|
||||
env.carrying = function(item)
|
||||
local inv = ent.inventory
|
||||
local count = 0
|
||||
for i, stack in ipairs(inv:get_list("main")) do
|
||||
local nn = stack:get_name()
|
||||
if nn == item then
|
||||
count = count + stack:get_count()
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
env.has_money = function()
|
||||
local inv = ent.inventory
|
||||
return currency.count_money(inv, "main")
|
||||
end
|
||||
|
||||
env.event = event
|
||||
|
||||
|
@ -804,7 +860,12 @@ people.get_fake_player = function(ent)
|
|||
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_wielded_item = function()
|
||||
if ent.wielded and ent.inventory:contains_item("main", ent.wielded) then
|
||||
return ItemStack(ent.wielded)
|
||||
end
|
||||
return ItemStack("")
|
||||
end,
|
||||
get_wield_index = defer(),
|
||||
get_wield_list = defer("main"),
|
||||
moveto = defer(),
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
if event.type == "program" then
|
||||
mem.cur = 0
|
||||
mem.actions = {
|
||||
|
||||
{"go", name="cowfarm"},
|
||||
{"wait", time=10},
|
||||
{"go", pos={x=39,y=11.5,z=189}},
|
||||
{"wait", time=10},
|
||||
{"gather", animal="cow",
|
||||
animal_wield="vessels:drinking_glass"},
|
||||
{"go", pos={x=54,y=11.5,z=181}},
|
||||
{"wait", time=10},
|
||||
{"go", pos={x=54,y=11.5,z=193}},
|
||||
{"wait", time=10},
|
||||
{"go", pos={x=40,y=11.5,z=193}},
|
||||
{"wait", time=10},
|
||||
{"go", pos={x=39,y=11.5,z=189}},
|
||||
{"gather"},
|
||||
{"wait", time=10},
|
||||
{"go", name="cowfarm"},
|
||||
|
||||
}
|
||||
|
||||
elseif event.type == "actfail" then
|
||||
|
||||
mem.cur = -1
|
||||
|
||||
elseif event.type == "act" then
|
||||
|
||||
if mem.cur == -1 then
|
||||
|
||||
mem.cur = 0
|
||||
action = {"go", name="cowfarmhouse",
|
||||
prevaction = {"wait", time=600}}
|
||||
|
||||
elseif mem.cur == 0 then
|
||||
|
||||
if carrying("animalmaterials:milk") > 0 then
|
||||
action = {"go", name="Farmer's Market",
|
||||
prevaction={"sell", item="animalmaterials:milk"}}
|
||||
return
|
||||
end
|
||||
|
||||
if carrying("vessels:drinking_glass") == 0 then
|
||||
|
||||
if has_money() < 5 then
|
||||
-- TODO - backup plan to get some money here!
|
||||
action = {"go", name="cowfarm",
|
||||
prevaction={"wait", time=120}}
|
||||
end
|
||||
|
||||
action = {"go", name="Cookshop",
|
||||
prevaction={"buy", item="vessels:drinking_glass", num=5}}
|
||||
return
|
||||
|
||||
else
|
||||
mem.cur = 1
|
||||
action = {"wait", time=5}
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
action = mem.actions[mem.cur]
|
||||
|
||||
mem.cur = mem.cur + 1
|
||||
if mem.cur > #mem.actions then
|
||||
mem.cur = 0
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue