497 lines
14 KiB
Lua
497 lines
14 KiB
Lua
aliveai_trader={}
|
|
|
|
aliveai.savedata.trader=function(self)
|
|
if self.trader then
|
|
return {
|
|
trader_inventory=self.trader_inventory,
|
|
trader=self.trader,
|
|
trader_select=self.trader_select,
|
|
}
|
|
end
|
|
|
|
if self.work_name then
|
|
return {
|
|
work_dig=self.work_dig,
|
|
work_take=self.work_take,
|
|
work_take_name=self.work_take_name,
|
|
work_place=self.work_place,
|
|
work_place_name=self.work_place_name,
|
|
work_add=self.work_add,
|
|
work_add_name=self.work_add_name,
|
|
work_name=self.work_name,
|
|
work_step=self.work_step
|
|
}
|
|
end
|
|
end
|
|
|
|
aliveai.loaddata.trade=function(self,r)
|
|
if r.trader then
|
|
self.trader_inventory=r.trader_inventory
|
|
self.trader=r.trader
|
|
self.trader_select=r.trader_select
|
|
end
|
|
if r.work_name then
|
|
self.work_dig=r.work_dig
|
|
self.work_take=r.work_take
|
|
self.work_take_name=r.work_take_name
|
|
self.work_place=r.work_place
|
|
self.work_place_name=r.work_place_name
|
|
self.work_add=r.work_add
|
|
self.work_add_name=r.work_add_name
|
|
self.work_name=r.work_name
|
|
self.work_step=r.work_step
|
|
end
|
|
return self
|
|
end
|
|
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Trades with players",
|
|
name="trader",
|
|
texture="aliveai_trader.png",
|
|
building=0,
|
|
annoyed_by_staring=0,
|
|
hp=40,
|
|
name_color="ffff00",
|
|
on_step=function(self,dtime)
|
|
if self.offering then
|
|
aliveai.rndwalk(self,false)
|
|
aliveai.stand(self)
|
|
return self
|
|
end
|
|
end,
|
|
click=function(self,clicker)
|
|
if not self.trader then
|
|
aliveai.say(self,"sorry, have no offer... try again")
|
|
self.spawn(self)
|
|
end
|
|
self.offering=true
|
|
aliveai.lookat(self,clicker:get_pos())
|
|
aliveai_trader.form(self,clicker)
|
|
end,
|
|
spawn=function(self)
|
|
self.botname="Trader: " .. self.botname
|
|
self.object:set_properties({nametag=self.botname,nametag_color="#" .. self.botname})
|
|
self.trader_inventory={}
|
|
self.trader={}
|
|
self.trader_select=1
|
|
local count=0
|
|
local c=1
|
|
aliveai.showstatus(self,"creating offer")
|
|
for i=0,20,1 do
|
|
for i, v in pairs(minetest.registered_items) do
|
|
if math.random(1,10)==1 and not self.trader_inventory[i] and minetest.get_item_group(i, "not_in_creative_inventory")==0 and minetest.get_all_craft_recipes(i) then
|
|
count=count+1
|
|
self.trader_inventory[i]=1
|
|
if count>=20 then break end
|
|
end
|
|
end
|
|
if count>=20 then break end
|
|
end
|
|
if count<1 then
|
|
self.trader_inventory=nil
|
|
aliveai.showstatus(self,"failed to create offer")
|
|
return self
|
|
end
|
|
count=0
|
|
for i=0,20,1 do
|
|
for i, v in pairs(minetest.registered_items) do
|
|
if math.random(1,20)==1 and not self.trader_inventory[i] and minetest.get_item_group(i, "not_in_creative_inventory")==0 and minetest.get_all_craft_recipes(i) then
|
|
count=count+1
|
|
c=math.random(5,20)
|
|
if v.stack_max<10 then c=aliveai.random(1,v.stack_max) end
|
|
self.trader[i]=c
|
|
if count>=10 then return self end
|
|
end
|
|
end
|
|
end
|
|
if count<1 then
|
|
self.trader_inventory=nil
|
|
self.trader=nil
|
|
aliveai.showstatus(self,"failed to create prices")
|
|
return self
|
|
end
|
|
end,
|
|
})
|
|
aliveai_trader.form=function(self,player)
|
|
local c=0
|
|
local gui=""
|
|
local but=""
|
|
local but2=""
|
|
local x=0
|
|
local y=0
|
|
local name=player:get_player_name()
|
|
if not aliveai_trader.user then aliveai_trader.user={} end
|
|
aliveai_trader.user[name]=self
|
|
for i, v in pairs(self.trader_inventory) do
|
|
c=c+1
|
|
but=but .. "item_image_button[" .. x.. "," .. y.. ";1,1;".. i ..";buy" .. c ..";]"
|
|
x=x+1
|
|
if x>=10 then x=0 y=y+1 end
|
|
end
|
|
x=-1
|
|
c=0
|
|
for i, v in pairs(self.trader) do
|
|
c=c+1
|
|
x=x+1
|
|
but2=but2 .. "item_image_button[" .. x.. ",3;1,1;".. i ..";pay" .. c ..";\n\n\b\b\b\b".. v .. "]"
|
|
end
|
|
gui=""
|
|
.."size[10,4]"
|
|
.. but
|
|
.."label[0,2;Pay with:]"
|
|
.."label[" .. (self.trader_select-1.2) ..",2.5;(Selected)]"
|
|
.. but2
|
|
minetest.after((0.1), function(gui)
|
|
return minetest.show_formspec(player:get_player_name(), "aliveai_trader.form",gui)
|
|
end, gui)
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, form, pressed)
|
|
if form=="aliveai_trader.form" then
|
|
local name=player:get_player_name()
|
|
local self=aliveai_trader.user[name]
|
|
|
|
if pressed.quit or not (self and self.object) then
|
|
if self and self.offering then self.offering=nil end
|
|
aliveai_trader.user[name]=nil
|
|
return self
|
|
end
|
|
|
|
for i=1,10,1 do
|
|
if pressed["pay" .. i] then
|
|
self.trader_select=i
|
|
aliveai_trader.form(self,player)
|
|
return self
|
|
end
|
|
end
|
|
|
|
for ii=1,20,1 do
|
|
if pressed["buy" .. ii] then
|
|
local c=0
|
|
for i, v in pairs(self.trader_inventory) do
|
|
c=c+1
|
|
if c==ii then
|
|
local cc=0
|
|
local inv=player:get_inventory()
|
|
if not inv:room_for_item("main", i) then minetest.chat_send_player(name, "Your inventory are full") return end
|
|
for iii, vv in pairs(self.trader) do
|
|
cc=cc+1
|
|
if cc==self.trader_select then
|
|
if not inv:contains_item("main", iii .. " " .. vv) then minetest.chat_send_player(name, "You dont have enough to buy") return end
|
|
inv:remove_item("main", iii .. " " .. vv)
|
|
aliveai.showstatus(self,"selling: " .. i .." for " .. iii .. " " .. vv)
|
|
end
|
|
end
|
|
inv:add_item("main", i)
|
|
return self
|
|
end
|
|
|
|
end
|
|
return self
|
|
end
|
|
end
|
|
aliveai_trader.user[name]=nil
|
|
return self
|
|
end
|
|
|
|
if form=="aliveai_worker.form" then
|
|
|
|
if not pressed.quit then return end
|
|
|
|
local pname=player:get_player_name()
|
|
local self=aliveai_trader.user[pname]
|
|
|
|
if not pressed.order or not (self and self.object) then
|
|
if self and self.offering then self.offering=nil end
|
|
aliveai_trader.user[pname]=nil
|
|
aliveai.give_to_bot(self,player)
|
|
return self
|
|
end
|
|
|
|
local names={}
|
|
local name=""
|
|
local name2=""
|
|
local node=""
|
|
local pos1={}
|
|
local pos2={}
|
|
|
|
if pressed.work1=="dig" then
|
|
local n=pressed.work2.split(pressed.work2,",")
|
|
for i, v in pairs(n) do
|
|
if v~=n and v~="" and (minetest.registered_nodes[v] or string.find(v,"group:")~=nil) then
|
|
table.insert(names,v)
|
|
else
|
|
minetest.chat_send_player(pname, v .." is not a node or group")
|
|
return
|
|
end
|
|
end
|
|
elseif pressed.work1=="take from inventory" then
|
|
local n=pressed.work2.split(pressed.work2,",")
|
|
local x=tonumber(n[1])
|
|
local y=tonumber(n[2])
|
|
local z=tonumber(n[3])
|
|
name=n[4]
|
|
if name==nil or name=="" then name="main" end
|
|
if x and y and z then
|
|
pos1={x=x,y=y,z=z}
|
|
else
|
|
if not (x and y and z) then minetest.chat_send_player(pname, "not all dimensions (x,y,z) is added")
|
|
else
|
|
minetest.chat_send_player(pname, "void position or name")
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
if pressed.work3=="place" then
|
|
local n=pressed.work4.split(pressed.work4,",")
|
|
local x=tonumber(n[1])
|
|
local y=tonumber(n[2])
|
|
local z=tonumber(n[3])
|
|
node=n[4]
|
|
if x and y and z and node and minetest.registered_nodes[node] then
|
|
pos2={x=x,y=y,z=z}
|
|
else
|
|
if not (x and y and z) then minetest.chat_send_player(pname, "not all dimensions (x,y,z) is added")
|
|
elseif node and not minetest.registered_nodes[node] then minetest.chat_send_player(pname, node .. " is not a node")
|
|
else
|
|
minetest.chat_send_player(pname, "void position or node")
|
|
end
|
|
return
|
|
end
|
|
elseif pressed.work3=="add to inventory" then
|
|
local n=pressed.work4.split(pressed.work4,",")
|
|
local x=tonumber(n[1])
|
|
local y=tonumber(n[2])
|
|
local z=tonumber(n[3])
|
|
name2=n[4]
|
|
if name2==nil or name2=="" then name2="main" end
|
|
if x and y and z then
|
|
pos2={x=x,y=y,z=z}
|
|
else
|
|
minetest.chat_send_player(pname, "not all dimensions (x,y,z) is added")
|
|
return
|
|
end
|
|
end
|
|
|
|
self.work_dig=nil
|
|
self.work_take=nil
|
|
self.work_take_name=nil
|
|
self.work_place=nil
|
|
self.work_place_name=nil
|
|
self.work_add=nil
|
|
self.work_add_name=nil
|
|
self.work_name=pname
|
|
self.work_step=1
|
|
|
|
if pressed.work1=="dig" then
|
|
self.work_dig=names
|
|
elseif pressed.work1=="take from inventory" then
|
|
self.work_take=pos1
|
|
self.work_take_name=name
|
|
end
|
|
|
|
if pressed.work3=="place" then
|
|
self.work_place=pos2
|
|
self.work_place_name=node
|
|
elseif pressed.work3=="add to inventory" then
|
|
self.work_add=pos2
|
|
self.work_add_name=name2
|
|
end
|
|
|
|
if pressed.quit or not (self and self.object) then
|
|
if self and self.offering then self.offering=nil end
|
|
aliveai_trader.user[pname]=nil
|
|
return self
|
|
end
|
|
aliveai_trader.user[pname]=nil
|
|
return self
|
|
end
|
|
end)
|
|
|
|
|
|
aliveai_trader.form2=function(self,player)
|
|
local name=player:get_player_name()
|
|
if not aliveai_trader.user then aliveai_trader.user={} end
|
|
aliveai_trader.user[name]=self
|
|
local work1=""
|
|
local work2=""
|
|
local id1=1
|
|
local id2=1
|
|
if self.work_dig then
|
|
local c=""
|
|
for i, v in pairs(self.work_dig) do
|
|
if i>1 then c="," end
|
|
work1=work1 .. c .. v
|
|
end
|
|
id1=1
|
|
end
|
|
if self.work_take then
|
|
work1=self.work_take.x .. "," .. self.work_take.y .."," .. self.work_take.z .."," ..self.work_take_name
|
|
id1=2
|
|
end
|
|
if self.work_place then
|
|
work2=self.work_place.x .. "," .. self.work_place.y .."," .. self.work_place.z .."," ..self.work_place_name
|
|
id2=1
|
|
end
|
|
if self.work_add then
|
|
work2=self.work_add.x .. "," .. self.work_add.y .."," .. self.work_add.z .."," ..self.work_add_name
|
|
id2=2
|
|
end
|
|
|
|
if not (self.work_place or self.work_add) then
|
|
local pppos=player:get_pos()
|
|
pppos=aliveai.roundpos(pppos)
|
|
work2=aliveai.strpos(pppos)
|
|
end
|
|
|
|
local gui=""
|
|
.."size[10,4]"
|
|
.."tooltip[work2;dig: default:dirt,group:stone...\ntake: x,y,z,inventory_name (default inventory name is main)]"
|
|
.."tooltip[work4;place: default:dirt,group:stone...\nadd: x,y,z,inventory_name (default inventory name is main)]"
|
|
.."dropdown[0,0;10,1;work1;dig,take from inventory;" .. id1 .."]"
|
|
.. "field[0,1;10,1;work2;;" .. work1 .."]"
|
|
.."dropdown[0,2;10,4;work3;place,add to inventory;" .. id2 .."]"
|
|
.. "field[0,3;10,1;work4;;" .. work2 .."]"
|
|
.."button_exit[0,3.2;2,2;order;order]"
|
|
minetest.after((0.1), function(gui)
|
|
return minetest.show_formspec(player:get_player_name(), "aliveai_worker.form",gui)
|
|
end, gui)
|
|
end
|
|
|
|
aliveai.create_bot({
|
|
description="Works for players",
|
|
name="worker",
|
|
texture="aliveai_worker.png",
|
|
building=0,
|
|
annoyed_by_staring=0,
|
|
hp=40,
|
|
name_color="ffff00",
|
|
crafting=0,
|
|
spawn=function(self)
|
|
self.botname="worker: " .. self.botname
|
|
self.object:set_properties({nametag=self.botname,nametag_color="#" .. self.botname})
|
|
end,
|
|
click=function(self,clicker)
|
|
if self.work_name and self.work_name~=clicker:get_player_name() then return end
|
|
self.offering=true
|
|
aliveai.lookat(self,clicker:get_pos())
|
|
aliveai_trader.form2(self,clicker)
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.offering then
|
|
aliveai.rndwalk(self,false)
|
|
aliveai.stand(self)
|
|
return self
|
|
end
|
|
--path
|
|
if self.work_path and self.path then
|
|
aliveai.path(self)
|
|
if self.done=="path" or (math.random(1,10)==1 and aliveai.distance(self,self.work_path)<self.arm and aliveai.visiable(self,self.work_path)) then
|
|
self.done=""
|
|
aliveai.lookat(self,self.work_path)
|
|
self.work_path=nil
|
|
--take from inventory
|
|
if self.work_step==1 and self.work_take then
|
|
local meta=minetest.get_meta(self.work_take)
|
|
local inv = meta:get_inventory()
|
|
local owner=meta:get_string("owner")
|
|
if owner=="" or owner==self.work_name then
|
|
for i=1,inv:get_size(self.work_take_name),1 do
|
|
local it=inv:get_stack(self.work_take_name,i):get_name()
|
|
local co=inv:get_stack(self.work_take_name,i):get_count()
|
|
inv:set_stack(self.work_take_name,i,nil)
|
|
aliveai.invadd(self,it,co)
|
|
end
|
|
end
|
|
self.work_step=2
|
|
return self
|
|
end
|
|
--place
|
|
if self.work_step==2 and self.work_place then
|
|
aliveai.place(self,self.work_place,self.work_place_name)
|
|
self.work_step=1
|
|
return self
|
|
end
|
|
--add to inventory
|
|
if self.work_step==2 and self.work_add then
|
|
local meta=minetest.get_meta(self.work_add)
|
|
local inv = meta:get_inventory()
|
|
local owner=meta:get_string("owner")
|
|
if owner=="" or owner==self.work_name then
|
|
for it, co in pairs(self.inv) do
|
|
if inv:room_for_item(self.work_add_name,it .. " " .. co) then
|
|
inv:add_item(self.work_add_name,it .. " " .. co)
|
|
aliveai.invadd(self,it,-co)
|
|
end
|
|
end
|
|
end
|
|
self.work_step=1
|
|
return self
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
--dig
|
|
if self.work_step==1 and self.work_dig then
|
|
if not self.mine then
|
|
aliveai.add_mine(self,self.work_dig,10)
|
|
self.crafting=0
|
|
return
|
|
elseif math.random(1,20)==1 then
|
|
for it, co in pairs(self.inv) do
|
|
if co>9 then
|
|
aliveai.exit_mine(self)
|
|
self.work_step=2
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--take from inventory
|
|
if self.work_step==1 and self.work_take then
|
|
local p=aliveai.neartarget(self,self.work_take,self.arm,0)
|
|
if p then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
pos.y=pos.y-1
|
|
p=aliveai.creatpath(self,pos,aliveai.roundpos(p))
|
|
if p then
|
|
self.path=p
|
|
self.work_path=self.work_take
|
|
end
|
|
end
|
|
return
|
|
end
|
|
--place
|
|
if self.work_step==2 and self.work_place then
|
|
local p=aliveai.neartarget(self,self.work_place,self.arm,0)
|
|
if p then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
pos.y=pos.y-1
|
|
p=aliveai.creatpath(self,pos,aliveai.roundpos(p))
|
|
if p then
|
|
self.path=p
|
|
self.work_path=self.work_place
|
|
end
|
|
end
|
|
return
|
|
end
|
|
--add to inventory
|
|
if self.work_step==2 and self.work_add then
|
|
local p=aliveai.neartarget(self,self.work_add,self.arm,0)
|
|
if p then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
pos.y=pos.y-1
|
|
p=aliveai.creatpath(self,pos,aliveai.roundpos(p))
|
|
if p then
|
|
self.path=p
|
|
self.work_path=self.work_add
|
|
end
|
|
end
|
|
return
|
|
end
|
|
end,
|
|
})
|