local S = minetest.get_translator("vg_mobs")

-- Fireball
local FIREBALL_VELOCITY = 7
local FIREBALL_OFFSET_MULT = 3

local fireball_boom_def = {
	radius = 2,
	damage_radius = 4,
	ignore_protection = true,
	explode_center = true,
}

local fireball_doubleboom_def = {
	radius = 4,
	damage_radius = 6,
	ignore_protection = true,
	explode_center = true,
}

core.register_entity("vg_mobs_mobs:dungeon_master_fireball", {
	initial_properties = {
		visual = "mesh",
		visual_size = vector.new(10, 10, 10),
		mesh = "vg_mobs_mobs_fireball.obj",
		textures = {"mobs_flat_fireball.png"},
		collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
		pointable = false,
		physical = true,
		collide_with_objects = true,
		glow = 8,
	},
	on_step = function(self, dtime, moveresult)
		local obj = self.object
		local pos = obj:get_pos()

		if not moveresult.collides then
			local node = core.get_node(pos)
			if core.get_item_group(node.name, "water") ~= 0 then
				core.sound_play("fire_extinguish_flame", {
					pos = pos,
					max_hear_distance = 16,
					gain = 0.4
				}, true)
				obj:remove()
				local falling_node = core.add_entity(pos, "__builtin:falling_node")
				if falling_node then
					falling_node:get_luaentity():set_node({name = "default:hardened_rock"})
				end
			end
			return
		end
		for _, collision in ipairs(moveresult.collisions) do
			if collision.type == "object" then
				local entity = collision.object:get_luaentity()
				if entity and entity.name == "vg_mobs_mobs:dungeon_master_fireball" then
					tnt.boom(pos, fireball_doubleboom_def)
					return obj:remove()
				end
			elseif collision.type == "node" then
				local node = core.get_node(collision.node_pos)
				if core.get_item_group(node.name, "explosive") > 0 then
					tnt.boom(pos, fireball_doubleboom_def)
					return obj:remove()
				end
			end
		end
		tnt.boom(pos, fireball_boom_def)
		return obj:remove()
	end,
	on_punch = function() end,
})

local function shoot_fireball(mob, dir)
	local obj = mob.object
	local pos = obj:get_pos()
	local fireball = core.add_entity(pos + (dir * FIREBALL_OFFSET_MULT), "vg_mobs_mobs:dungeon_master_fireball")
	if not fireball then return end
	core.sound_play("mobs_fireball", {pos = pos}, true)
	fireball:set_rotation(vector.random_direction()) -- just a cool effect
	fireball:set_velocity(dir * FIREBALL_VELOCITY)
end
vg_mobs_mobs.shoot_dm_fireball = shoot_fireball

-- Dungeon Master
local RANDOM_SOUND_TIMER_MIN = 5000
local RANDOM_SOUND_TIMER_MAX = 40000
local VIEW_RANGE = 15
local ANGRY_COOLDOWN_TIME = 16

local TASK_QUEUE_ROAM_SETTINGS = {
	walk_speed = 1,
	hunt_speed = 2,
	liquid_rise_speed = 2,
	jump_strength = 7,
	jump_clear_height = 2,
	fall_height = 8,
	walk_duration_min = 10000,
	walk_duration_max = 20000,
	find_land_duration_min = 7000,
	find_land_duration_max = 10000,
	find_safe_land_duration_min = 1000,
	find_safe_land_duration_max = 1100,
	idle_duration_min = 500,
	idle_duration_max = 6000,
	find_land_length = 20,
	follow_max_distance = VIEW_RANGE,
	follow_reach_distance = 10,
	follow_give_up_time = 10.0,
	no_follow_time = 6.0,

	--dogfight = true,
	--dogfight_range = 3,
	--dogfight_toolcaps = {damage_groups = {fleshy = 3}},
	--dogfight_interval = 1.0,
	shoot = true,
	shoot_range = 10,
	shoot_function = shoot_fireball,
	shoot_interval = 15.0,
}

vg_mobs.register_mob("vg_mobs_mobs:dungeon_master", {
	description = S("Dungeon Master"),
	drops = {
		{name = "default:mese_crystal_fragment", chance = 0.5, min = 0, max = 1},
	},
	default_sounds = {
		attack = "default_swoosh2",
		call = "mobs_dungeonmaster",
		damage = "mobs_dungeonmaster",
		punch_no_damage = "default_swoosh1",
		death = "mobs_dungeonmaster",
	},
	animations = {
		idle = {frame_range = {x = 0, y = 19}, default_frame_speed = 15},
		dead_static = {frame_range = {x = 0, y = 0}},
		walk = {frame_range = {x = 20, y = 35}, default_frame_speed = 15},
		run = {frame_range = {x = 20, y = 35}, default_frame_speed = 15},
		punch = {frame_range = {x = 36, y = 48}, default_frame_speed = 15},
		shoot = {frame_range = {x = 36, y = 48}, default_frame_speed = 15},
	},
	front_body_point = vector.new(0, -1.2, 0),
	dead_y_offset = 0.6,
	entity_definition = {
		initial_properties = {
			hp_max = 40,
			physical = true,
			collisionbox = {-0.7, -1, -0.7, 0.7, 1.6, 0.7},
			selectionbox = {-0.7, -1, -0.7, 0.7, 1.6, 0.7, rotate=true},
			visual = "mesh",
			mesh = "mobs_dungeon_master.b3d",
			textures = {"mobs_dungeon_master.png"},
			makes_footstep_sound = true,
			stepheight = 1.1,
		},
		on_activate = function(self, staticdata)
			vg_mobs.init_mob(self)
			vg_mobs.restore_state(self, staticdata)

			vg_mobs.init_fall_damage(self, true)

			vg_mobs.init_tasks(self)
			vg_mobs.add_task_queue(self, vg_mobs.task_queues.land_roam(TASK_QUEUE_ROAM_SETTINGS))
			vg_mobs.add_task_queue(self, vg_mobs.task_queues.player_follow_scan(VIEW_RANGE))
			vg_mobs.add_task_queue(self, vg_mobs.create_task_queue(
				vg_mobs.create_angry_cooldown_decider(VIEW_RANGE, ANGRY_COOLDOWN_TIME)))
			vg_mobs.add_task_queue(self, vg_mobs.create_task_queue(vg_mobs.create_player_angry_decider()))
			vg_mobs.add_task_queue(self, vg_mobs.task_queues.call_sound(RANDOM_SOUND_TIMER_MIN, RANDOM_SOUND_TIMER_MAX))
		end,
		get_staticdata = vg_mobs.get_staticdata_default,
		on_step = function(self, dtime, moveresult)
			vg_mobs.handle_dying(self, dtime, moveresult, vg_mobs.get_dying_step(true, false))
			vg_mobs.scan_environment(self, dtime, -0.5)
			vg_mobs.handle_environment_damage(self, dtime, moveresult)
			vg_mobs.handle_tasks(self, dtime, moveresult)
		end,
		on_death = vg_mobs.on_death_default,
		on_punch = vg_mobs.on_punch_default,
	},
})

-- Register spawn egg
vg_mobs.register_egg("vg_mobs_mobs:dungeon_master", "default_lava.png")

-- Define spawn rules
vg_mobs_spawn.register_spawn("vg_mobs_mobs:dungeon_master", {
	nodes = {"default:mossycobble", "nether:rack", "nether:rack_deep"},
	neighbors = {"default:mese", "default:stone_with_mese", "nether:rack", "default:mossycobble"},
	chance = 5000,
	active_object_limit = 3,
	active_object_limit_wider = 3,
})
