group behavoir, many other things

master
Izzy 2017-08-13 22:04:32 -07:00
parent 916abc25b3
commit d6e0538463
7 changed files with 391 additions and 37 deletions

View File

@ -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,
})

View File

@ -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)

View File

@ -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,
})

View File

@ -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
View File

@ -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)
--[[

View File

@ -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")

View File

@ -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