group behavoir, many other things
parent
916abc25b3
commit
d6e0538463
|
@ -72,13 +72,27 @@ bt.register_action("SetNode", {
|
|||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(sel)
|
||||
return {
|
||||
sel = sel
|
||||
}
|
||||
end,
|
||||
ctor = function(sel) return { sel = sel } end,
|
||||
})
|
||||
|
||||
bt.register_action("IsNode", {
|
||||
tick = function(node, data)
|
||||
if data.targetPos == nil then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
local n = minetest.get_node(data.targetPos)
|
||||
if n == nil or n.name ~= node.sel then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(sel) return { sel = sel } end,
|
||||
})
|
||||
|
||||
|
||||
bt.register_action("ExtinguishFire", {
|
||||
tick = function(node, data)
|
||||
print("Extinguishing nearby fire")
|
||||
|
@ -156,11 +170,7 @@ bt.register_action("PutInChest", {
|
|||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(sel)
|
||||
return {
|
||||
sel = sel
|
||||
}
|
||||
end,
|
||||
ctor = function(sel) return { sel = sel } end,
|
||||
})
|
||||
|
||||
|
||||
|
@ -169,16 +179,33 @@ bt.register_action("Die", {
|
|||
tick = function(node, data)
|
||||
print("Dying now")
|
||||
|
||||
-- TODO: remove inv and global data
|
||||
|
||||
data.mob.object:remove()
|
||||
|
||||
return "success"
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
bt.register_action("Spawn", {
|
||||
tick = function(node, data)
|
||||
local pos = {x = data.targetPos.x, y = data.targetPos.y + 2, z = data.targetPos.z}
|
||||
|
||||
local name = "giants:giant_"..node.role
|
||||
local mob = minetest.add_entity(pos, name)
|
||||
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(role) return { role = role } end,
|
||||
})
|
||||
|
||||
|
||||
bt.register_action("PickUpNearbyItems", {
|
||||
tick = function(node, data)
|
||||
|
||||
local objects = minetest.get_objects_inside_radius(data.pos, data.mob.reach)
|
||||
local objects = minetest.get_objects_inside_radius(data.pos, node.dist)
|
||||
for _,object in ipairs(objects) do
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
|
||||
if object:get_luaentity().itemstring == node.sel then
|
||||
|
@ -195,9 +222,10 @@ bt.register_action("PickUpNearbyItems", {
|
|||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(sel)
|
||||
ctor = function(sel, dist)
|
||||
return {
|
||||
sel = sel
|
||||
sel = sel,
|
||||
dist = dist,
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -369,6 +369,49 @@ bt.register_action("Counter", {
|
|||
})
|
||||
|
||||
|
||||
bt.register_action("Animate", {
|
||||
tick = function(node, data)
|
||||
set_animation(data.mob, node.anim)
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(anim) return { anim= anim } end,
|
||||
})
|
||||
|
||||
bt.register_action("Wield", {
|
||||
tick = function(node, data)
|
||||
data.mob.object:set_wielded_item(node.item)
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(item) return { item= item } end,
|
||||
})
|
||||
|
||||
|
||||
bt.register_action("SetRole", {
|
||||
tick = function(node, data)
|
||||
data.role = node.role
|
||||
|
||||
if data.groupID ~= nil then
|
||||
local gd = giants.groupData[data.groupID]
|
||||
if gd == nil then
|
||||
return "success"
|
||||
end
|
||||
|
||||
if gd.members[data.mob.inv_id] == nil then
|
||||
gd.members[data.mob.inv_id] = {}
|
||||
end
|
||||
|
||||
gd.members[data.mob.inv_id].role = node.role
|
||||
end
|
||||
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(role) return { role= role } end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
bt.register_action("Print", {
|
||||
tick = function(node, data)
|
||||
|
|
|
@ -177,4 +177,61 @@ bt.register_action("GetWaypoint", {
|
|||
})
|
||||
|
||||
|
||||
bt.register_action("SetGroupWaypoint", {
|
||||
tick = function(node, data)
|
||||
if data.targetPos == nil or data.groupID == nil or giants.groupData[data.groupID] == nil then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
giants.groupData[data.groupID].waypoints[node.wpname] = data.targetPos
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(name)
|
||||
return {
|
||||
wpname=name or "_"
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
bt.register_action("GetGroupWaypoint", {
|
||||
tick = function(node, data)
|
||||
if giants.groupData[data.groupID].waypoints[node.wpname] == nil then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
data.targetPos = giants.groupData[data.groupID].waypoints[node.wpname]
|
||||
return "success"
|
||||
end,
|
||||
|
||||
ctor = function(name)
|
||||
return {
|
||||
wpname=name or "_"
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
bt.register_action("PushTarget", {
|
||||
tick = function(node, data)
|
||||
if data.targetPos == nil then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
table.insert(data.posStack, data.targetPos)
|
||||
return "success"
|
||||
end,
|
||||
})
|
||||
|
||||
bt.register_action("PopTarget", {
|
||||
tick = function(node, data)
|
||||
if #data.posStack == 0 then
|
||||
return "failed"
|
||||
end
|
||||
|
||||
data.targetPos = table.remove(data.posStack)
|
||||
return "success"
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
|
@ -515,3 +515,65 @@ bt.register_action("MoveTarget", {
|
|||
}
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
bt.register_action("MoveTargetRandom", {
|
||||
tick = function(node, data)
|
||||
if data.targetPos == nil then
|
||||
print("no active target")
|
||||
return "failed"
|
||||
end
|
||||
|
||||
return "success"
|
||||
end,
|
||||
|
||||
reset = function(node, data)
|
||||
if data.targetPos == nil then -- game restarts cause this
|
||||
return
|
||||
end
|
||||
|
||||
data.targetPos.x = data.targetPos.x + math.random(-node.range.x, node.range.x)
|
||||
data.targetPos.y = data.targetPos.y + math.random(-node.range.y, node.range.y)
|
||||
data.targetPos.z = data.targetPos.z + math.random(-node.range.z, node.range.z)
|
||||
end,
|
||||
|
||||
ctor = function(range)
|
||||
return {
|
||||
range = range,
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- used for group identity
|
||||
bt.register_action("FindGroupCampfire", {
|
||||
tick = function(node, data)
|
||||
if data.groupID ~= nil then -- already has a group
|
||||
if giants.groupData[data.groupID] ~= nil then
|
||||
return "success"
|
||||
end
|
||||
end
|
||||
|
||||
local cf = minetest.find_node_near(data.pos, 50, {name="giants:campfire"})
|
||||
if cf ~= nil then
|
||||
local key = cf.x..":"..cf.y..":"..cf.z
|
||||
data.groupID = key
|
||||
return "success"
|
||||
else
|
||||
return "failed"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
bt.register_action("HasGroup", {
|
||||
tick = function(node, data)
|
||||
if data.groupID ~= nil then -- already has a group
|
||||
if giants.groupData[data.groupID] ~= nil then
|
||||
return "success"
|
||||
end
|
||||
end
|
||||
|
||||
return "failed"
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
103
giant.lua
103
giant.lua
|
@ -2,9 +2,12 @@
|
|||
|
||||
local lumberjack = function()
|
||||
return bt.Sequence("", {
|
||||
bt.Succeed(bt.FindGroupCampfire()),
|
||||
|
||||
-- build a chest and remember where it is
|
||||
bt.FindSpotOnGround(),
|
||||
bt.SetNode({name="default:chest"}),
|
||||
--bt.FindSpotOnGround(),
|
||||
--bt.SetNode({name="default:chest"}),
|
||||
bt.GetGroupWaypoint("lumber_chest"),
|
||||
bt.SetWaypoint("chest"),
|
||||
|
||||
bt.UntilFailed(bt.Sequence("logs some trees", {
|
||||
|
@ -21,18 +24,22 @@ local lumberjack = function()
|
|||
|
||||
-- chop it down
|
||||
bt.Invert(bt.UntilFailed(bt.Sequence("chop tree", {
|
||||
bt.Wield("default:axe_steel"),
|
||||
bt.Animate("punch"),
|
||||
bt.FindNodeNear({"group:tree"}, 3),
|
||||
bt.DigNode(),
|
||||
bt.WaitTicks(1),
|
||||
}))),
|
||||
bt.SetWaypointHere("tree"),
|
||||
|
||||
bt.Wield(""),
|
||||
|
||||
|
||||
--[[ broken
|
||||
bt.Succeed(bt.Sequence("pick up saplings", {
|
||||
bt.FindItemNear("group:sapling", 20),
|
||||
bt.PickUpNearbyItems("group:sapling"),
|
||||
--bt.FindItemNear("group:sapling", 20),
|
||||
bt.PickUpNearbyItems("group:sapling", 5),
|
||||
})),
|
||||
]]
|
||||
|
||||
|
||||
-- put wood in chest
|
||||
bt.GetWaypoint("chest"),
|
||||
|
@ -40,8 +47,8 @@ local lumberjack = function()
|
|||
bt.PutInChest(nil),
|
||||
|
||||
|
||||
|
||||
bt.Print("end of loop"),
|
||||
bt.WaitTicks(1),
|
||||
bt.Print("end of loop \n"),
|
||||
}))
|
||||
})
|
||||
end
|
||||
|
@ -59,6 +66,7 @@ local dig_region = function(item)
|
|||
bt.Invert(bt.UntilFailed(bt.Sequence("dig hole", {
|
||||
bt.FindNodeInRange(item),
|
||||
bt.Approach(3),
|
||||
bt.Animate("punch"),
|
||||
bt.DigNode(),
|
||||
bt.WaitTicks(1),
|
||||
}))),
|
||||
|
@ -70,6 +78,8 @@ end
|
|||
|
||||
local dig_hole = function(item)
|
||||
return bt.Sequence("", {
|
||||
bt.Succeed(bt.FindGroupCampfire()),
|
||||
|
||||
-- find a place for a hole
|
||||
bt.FindSpotOnGround(),
|
||||
bt.SetWaypoint("hole"),
|
||||
|
@ -102,6 +112,7 @@ local fill_region = function(item)
|
|||
bt.Invert(bt.UntilFailed(bt.Sequence("fill region", {
|
||||
bt.FindNodeInRange({"air"}),
|
||||
bt.Approach(3),
|
||||
bt.Animate("punch"),
|
||||
bt.SetNode(item),
|
||||
bt.WaitTicks(1),
|
||||
}))),
|
||||
|
@ -123,6 +134,7 @@ local fence_region = function(item)
|
|||
bt.Invert(bt.UntilFailed(bt.Sequence("fill region", {
|
||||
bt.FindPerimeterNodeInRegion({"air"}),
|
||||
bt.Approach(3),
|
||||
bt.Animate("punch"),
|
||||
bt.SetNode(item);
|
||||
bt.WaitTicks(1),
|
||||
}))),
|
||||
|
@ -134,6 +146,8 @@ end
|
|||
|
||||
local build_house = function(item)
|
||||
return bt.Sequence("", {
|
||||
bt.Succeed(bt.FindGroupCampfire()),
|
||||
|
||||
-- find a place for a hole
|
||||
bt.FindSpotOnGround(),
|
||||
bt.SetWaypoint("house"),
|
||||
|
@ -160,17 +174,24 @@ local build_house = function(item)
|
|||
})
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local build_campfire = function()
|
||||
return bt.Sequence("build campfire", {
|
||||
bt.FindSpotOnGround(),
|
||||
bt.SetWaypoint("campfire"),
|
||||
|
||||
bt.FindRegionAround(2),
|
||||
dig_region({"group:soil", "group:plant", "group:sand"}),
|
||||
fill_region({name="default:gravel"}),
|
||||
-- bt.FindRegionAround(2),
|
||||
-- dig_region({"group:soil", "group:plant", "group:sand"}),
|
||||
-- fill_region({name="default:gravel"}),
|
||||
|
||||
bt.GetWaypoint("campfire"),
|
||||
|
||||
bt.MoveTarget({x=0, y=-1, z=0}),
|
||||
|
||||
bt.Animate("punch"),
|
||||
|
||||
bt.DigNode(),
|
||||
bt.SetNode({name="default:coalblock"}),
|
||||
bt.WaitTicks(1),
|
||||
|
@ -192,18 +213,65 @@ local build_campfire = function()
|
|||
bt.WaitTicks(1),
|
||||
|
||||
bt.MoveTarget({x=0, y=0, z=1}),
|
||||
bt.SetNode({name="fire:permanent_flame"}),
|
||||
|
||||
bt.SetNode({name="giants:campfire"}),
|
||||
|
||||
|
||||
bt.Die()
|
||||
bt.FindGroupCampfire(),
|
||||
bt.SetRole("founder"),
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
|
||||
local spawn_at_campfire = function(role)
|
||||
return bt.Sequence("spawn at campfire", {
|
||||
bt.PushTarget(),
|
||||
bt.GetGroupWaypoint("spawnpoint"),
|
||||
bt.MoveTargetRandom({x=1, y=0, z=1}),
|
||||
bt.Spawn(role),
|
||||
bt.PopTarget(),
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
local found_village = function()
|
||||
return bt.Sequence("founding village", {
|
||||
build_campfire(),
|
||||
|
||||
bt.MoveTarget({x=2, y=0, z=2}),
|
||||
bt.SetGroupWaypoint("spawnpoint"),
|
||||
|
||||
bt.MoveTarget({x=-5, y=0, z=1}),
|
||||
bt.SetGroupWaypoint("lumber_chest"),
|
||||
bt.SetNode({name="default:chest"}),
|
||||
|
||||
bt.MoveTarget({x=0, y=0, z=-6}),
|
||||
bt.SetGroupWaypoint("stone_chest"),
|
||||
bt.SetNode({name="default:chest"}),
|
||||
|
||||
bt.MoveTarget({x=6, y=0, z=6}),
|
||||
bt.SetGroupWaypoint("food_chest"),
|
||||
bt.SetNode({name="default:chest"}),
|
||||
|
||||
bt.WaitTicks(1),
|
||||
spawn_at_campfire("lumberjack"),
|
||||
|
||||
bt.WaitTicks(2),
|
||||
spawn_at_campfire("lumberjack"),
|
||||
|
||||
--build_house(),
|
||||
|
||||
bt.Die(),
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local quarry = function(item)
|
||||
return bt.Sequence("", {
|
||||
bt.Succeed(bt.FindGroupCampfire()),
|
||||
|
||||
-- build a chest and remember where it is
|
||||
bt.FindSpotOnGround(),
|
||||
bt.SetNode({name="default:chest"}),
|
||||
|
@ -224,6 +292,7 @@ local quarry = function(item)
|
|||
-- chop it down
|
||||
bt.Counter("foo", "set", 0),
|
||||
bt.Invert(bt.UntilFailed(bt.Sequence("chop tree", {
|
||||
bt.Animate("punch"),
|
||||
bt.FindNodeNear(item, 2),
|
||||
bt.DigNode(),
|
||||
bt.WaitTicks(1),
|
||||
|
@ -378,7 +447,7 @@ make_giant("builder", function()
|
|||
end)
|
||||
|
||||
make_giant("founder", function()
|
||||
return build_campfire()
|
||||
return found_village()
|
||||
end)
|
||||
|
||||
--[[
|
||||
|
|
86
init.lua
86
init.lua
|
@ -1,5 +1,25 @@
|
|||
local path = minetest.get_modpath("giants")
|
||||
|
||||
giants = {
|
||||
groupData= {},
|
||||
mobsAlive= {},
|
||||
}
|
||||
|
||||
|
||||
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
|
||||
local storagedata = mod_storage:to_table() -- Assuming there are only messages in the mod configuration
|
||||
if storagedata ~= nil and storagedata.groupData ~= nil then
|
||||
giants = storagedata
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
mod_storage:from_table(giants)
|
||||
end)
|
||||
|
||||
|
||||
-- Mob Api
|
||||
|
||||
dofile(path.."/api.lua")
|
||||
|
@ -11,10 +31,74 @@ dofile(path.."/simple_api.lua")
|
|||
dofile(path.."/giant.lua")
|
||||
|
||||
|
||||
minetest.register_node("giants:campfire", {
|
||||
description = "Campfire",
|
||||
drawtype = "firelike",
|
||||
tiles = {
|
||||
{
|
||||
name = "fire_basic_flame_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1
|
||||
},
|
||||
},
|
||||
},
|
||||
inventory_image = "fire_basic_flame.png",
|
||||
paramtype = "light",
|
||||
light_source = 13,
|
||||
walkable = false,
|
||||
buildable_to = false,
|
||||
sunlight_propagates = true,
|
||||
damage_per_second = 8,
|
||||
groups = {igniter = 2, cracky=3},
|
||||
drop = "",
|
||||
on_construct = function(pos)
|
||||
local key = pos.x..":"..pos.y..":"..pos.z
|
||||
if giants.groupData[key] == nil then
|
||||
giants.groupData[key] = {
|
||||
pos = {x= pos.x, y= pos.y, z= pos.z},
|
||||
roles = {},
|
||||
members = {},
|
||||
waypoints = {},
|
||||
}
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Smoke",
|
||||
nodenames = {"giants:campfire"},
|
||||
interval = 5,
|
||||
chance = 0,
|
||||
action = function(pos)
|
||||
pos.y = pos.y + 1
|
||||
minetest.add_particlespawner({
|
||||
amount = 4,
|
||||
time = 5,
|
||||
minpos = vector.subtract(pos, 1 / 4),
|
||||
maxpos = vector.add(pos, 1 / 4),
|
||||
minvel = {x=-0.05, y=.5, z=-0.05},
|
||||
maxvel = {x=0.05, y=1.5, z=0.05},
|
||||
minacc = {x=-0.05, y=0.1, z=-0.05},
|
||||
maxacc = {x=0.05, y=0.3, z=0.05},
|
||||
minexptime = 7,
|
||||
maxexptime = 12,
|
||||
minsize = 5,
|
||||
maxsize = 8,
|
||||
texture = "tnt_smoke.png^[colorize:black:120",
|
||||
})
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
-- Mob Items
|
||||
--dofile(path.."/crafts.lua")
|
||||
|
||||
-- Spawner
|
||||
--dofile(path.."/spawner.lua")
|
||||
|
||||
print ("[MOD] Giants loaded")
|
||||
print ("[MOD] Giants loaded")
|
||||
|
|
|
@ -133,7 +133,7 @@ minetest.register_entity(name, {
|
|||
|
||||
-- inventories cannot be serialized and cause the game to crash if
|
||||
-- placed in the entity's table
|
||||
local inv = minetest.get_inventory({type="detached", name=btdata.id})
|
||||
local inv = minetest.get_inventory({type="detached", name=self.inv_id})
|
||||
btdata.inv = inv
|
||||
|
||||
bt.tick(self.bt, btdata)
|
||||
|
@ -393,20 +393,22 @@ minetest.register_entity(name, {
|
|||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
self.btData = {
|
||||
id= name..":"..math.random(1, 2000000000),
|
||||
groupID = "default",
|
||||
|
||||
waypoints= {},
|
||||
counters={},
|
||||
|
||||
history={},
|
||||
history_queue={},
|
||||
history_depth=20,
|
||||
|
||||
posStack={},
|
||||
}
|
||||
|
||||
local btdata = self.btData
|
||||
|
||||
print(btdata.id)
|
||||
local inventory = minetest.create_detached_inventory(btdata.id, {})
|
||||
inventory:set_size("main", 9)
|
||||
self.inv_id= name..":"..math.random(1, 2000000000)
|
||||
--print(btdata.id)
|
||||
|
||||
btdata.lastpos = self.object:getpos()
|
||||
|
||||
|
@ -431,6 +433,10 @@ minetest.register_entity(name, {
|
|||
return
|
||||
end
|
||||
|
||||
local inventory = minetest.create_detached_inventory(self.inv_id, {})
|
||||
inventory:set_size("main", 9)
|
||||
|
||||
|
||||
-- select random texture, set model and size
|
||||
if not self.base_texture then
|
||||
|
||||
|
@ -521,7 +527,12 @@ minetest.register_entity(name, {
|
|||
self.attack = nil
|
||||
self.following = nil
|
||||
self.state = "stand"
|
||||
|
||||
|
||||
if self.btData ~= nil then
|
||||
self.btData.inv = nil -- just in case
|
||||
self.btData.mob = nil -- just in case
|
||||
end
|
||||
|
||||
-- used to rotate older mobs
|
||||
if self.drawtype
|
||||
and self.drawtype == "side" then
|
||||
|
|
Loading…
Reference in New Issue