2024-12-29 14:57:41 +05:30

221 lines
7.2 KiB
Lua

-- Include the player_api for animations
dofile(minetest.get_modpath("player_api") .. "/api.lua")
minetest.register_entity("practice_bot:bot", {
hp_max = 40,
physical = true,
collisionbox = {-0.3, 0, -0.3, 0.3, 1.7, 0.3},
visual = "mesh",
mesh = "character.b3d",
textures = {"character.png"},
animations = {
stand = {x = 0, y = 79},
walk = {x = 168, y = 187},
attack = {x = 189, y = 198},
},
animation_speed = 30,
current_animation = "stand",
attack_range = 20,
attack_damage = 2,
cooldown = 0.1,
last_attack_time = 0,
speed = 4,
bot_type = "easy",
set_animation = function(self, animation)
if self.current_animation ~= animation then
local anim = self.animations[animation]
if anim then
self.object:set_animation(anim, self.animation_speed, 0)
self.current_animation = animation
end
end
end,
on_step = function(self, dtime)
local pos = self.object:get_pos()
local velocity = self.object:get_velocity()
local players = minetest.get_connected_players()
local nearest_player = nil
local nearest_distance = self.attack_range
for _, player in ipairs(players) do
local player_pos = player:get_pos()
local distance = vector.distance(pos, player_pos)
if distance <= self.attack_range and distance < nearest_distance then
nearest_player = player
nearest_distance = distance
end
end
if not self.is_on_ground then
velocity.y = velocity.y - 9.8 * dtime
end
if nearest_player then
local player_pos = nearest_player:get_pos()
local distance = vector.distance(pos, player_pos)
local dir = vector.subtract(player_pos, pos)
dir.y = 0
local yaw = math.atan2(dir.z, dir.x) - math.pi / 2
self.object:set_yaw(yaw)
if distance > 1 then
self:set_animation("walk")
local new_velocity = vector.multiply(vector.normalize(dir), self.speed)
new_velocity.y = velocity.y
self.object:set_velocity(new_velocity)
else
local current_time = minetest.get_gametime()
if current_time - self.last_attack_time >= self.cooldown then
self:set_animation("attack")
nearest_player:punch(self.object, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = self.attack_damage}})
self.last_attack_time = current_time
end
self.object:set_velocity({x = 0, y = velocity.y, z = 0})
end
else
self:set_animation("stand")
self.object:set_velocity({x = 0, y = velocity.y, z = 0})
end
local node_below = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
self.is_on_ground = node_below and minetest.registered_nodes[node_below.name] and minetest.registered_nodes[node_below.name].walkable
if self.is_on_ground and velocity.y == 0 then
local step_pos = vector.add(pos, vector.multiply(vector.normalize({x = velocity.x, y = 0, z = velocity.z}), 0.5))
step_pos.y = step_pos.y + 0.5
local step_node = minetest.get_node_or_nil(step_pos)
if step_node and minetest.registered_nodes[step_node.name] and minetest.registered_nodes[step_node.name].walkable then
self.object:set_velocity({x = velocity.x, y = 6, z = velocity.z})
end
end
end
})
local function spawn_practice_bot(pos, config)
local bot_pos = vector.add(pos, {x = 0, y = 1, z = 0})
local bot = minetest.add_entity(bot_pos, "practice_bot:bot")
if bot then
local bot_lua = bot:get_luaentity()
if bot_lua then
bot_lua.hp_max = config.hp_max
bot_lua.object:set_hp(config.hp_max)
bot_lua.speed = config.speed
bot_lua.attack_damage = config.attack_damage
bot_lua.cooldown = config.cooldown
end
end
end
minetest.register_tool("practice_bot:spawner_breaker", {
description = "Spawner Breaker Axe",
inventory_image = "spawner_breaker.png",
tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level = 1,
groupcaps = {
spawner_breakable = {times = {[1] = 1.0, [2] = 0.5, [3] = 0.2}, uses = 30, maxlevel = 3},
},
damage_groups = {fleshy = 5},
},
})
minetest.register_node("practice_bot:easy_spawner", {
description = "Easy Bot Spawner",
tiles = {"spawner_top.png", "easy_spawner_side.png"},
groups = {spawner_breakable = 1},
on_rightclick = function(pos)
spawn_practice_bot(pos, {
hp_max = 10,
speed = 2,
attack_damage = 1,
cooldown = 1.0
})
end
})
minetest.register_node("practice_bot:medium_spawner", {
description = "Medium Bot Spawner",
tiles = {"spawner_top.png", "medium_spawner_side.png"},
groups = {spawner_breakable = 1},
on_rightclick = function(pos)
spawn_practice_bot(pos, {
hp_max = 20,
speed = 3,
attack_damage = 2,
cooldown = 0.5
})
end
})
minetest.register_node("practice_bot:difficult_spawner", {
description = "Difficult Bot Spawner",
tiles = {"spawner_top.png", "hard_spawner_side.png"},
groups = {spawner_breakable = 1},
on_rightclick = function(pos)
spawn_practice_bot(pos, {
hp_max = 30,
speed = 5,
attack_damage = 4,
cooldown = 0.3
})
end
})
minetest.register_craftitem("practice_bot:easy_spawner_item", {
description = "Easy Bot Spawner Item",
inventory_image = "easy_spawner_side.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.under then
spawn_practice_bot(pointed_thing.under, {
hp_max = 10,
speed = 2,
attack_damage = 1,
cooldown = 1.0
})
itemstack:take_item()
end
return itemstack
end
})
minetest.register_craftitem("practice_bot:medium_spawner_item", {
description = "Medium Bot Spawner Item",
inventory_image = "medium_spawner_side.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.under then
spawn_practice_bot(pointed_thing.under, {
hp_max = 20,
speed = 3,
attack_damage = 2,
cooldown = 0.5
})
itemstack:take_item()
end
return itemstack
end
})
minetest.register_craftitem("practice_bot:difficult_spawner_item", {
description = "Difficult Bot Spawner Item",
inventory_image = "hard_spawner_side.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.under then
spawn_practice_bot(pointed_thing.under, {
hp_max = 30,
speed = 5,
attack_damage = 4,
cooldown = 0.3
})
itemstack:take_item()
end
return itemstack
end
})