
-- Note: file is not secret. Contents intentionally revealed.



-- Despawn oerkki. Note: despawn effect must appear the same as the teleport
-- effect. Players should not be able to tell the difference.
local function despawn(self)
	local pos = self.object:get_pos()
	ambiance.sound_play("nether_portal_usual", pos, 1.0, 20)
	preload_tp.spawn_particles(pos)
	self.mkrm = true
end



-- Teleport to somewhere nearby.
local function teleport(self)
	-- The oerkki teleports some distance away.
	local pos = self.object:get_pos()
	p = vector.round(pos)
	p.x = p.x + math.random(-70, 70)
	p.z = p.z + math.random(-70, 70)
	p.y = p.y + math.random(-15, 15)

	local minp = vector.add(p, {x=-10, y=-10, z=-10})
	local maxp = vector.add(p, {x=10, y=10, z=10})
	local targets = hb4.find_walkable_in_area_under_unwalkable(minp, maxp)
	if #targets == 0 then
		return
	end

	local target = targets[math.random(1, #targets)]
	self.object:set_pos(target)

	-- Play sound/particle effect.
	ambiance.sound_play("nether_portal_usual", pos, 1.0, 20)
	preload_tp.spawn_particles(pos)

	-- A 2/3 chance Oerkki heals.
	if math.random(1, 3) > 1 then
		self.health = math.random(self.hp_min, self.hp_max)
	end

	-- Stop any current activity.
	self.attack = nil
	mobs.transition_state(self, "")
end



-- The oerkki teleports to a location the player has recently been.
local function prevpos(self)
	local pos = self.object:get_pos()

	-- We can assume the nearest player to us is the right one.
	local pref = hb4.nearest_player(pos)
	if not pref then
		return
	end

	local pname = pref:get_player_name()
	local positions = ap.get_position_list(pname)

	if #positions == 0 then
		return
	end

	local data = positions[math.random(1, #positions)]
	local target = data.pos
	self.object:set_pos(target)

	-- Play sound/particle effect.
	ambiance.sound_play("nether_portal_usual", pos, 1.0, 20)
	preload_tp.spawn_particles(pos)

	-- A 1/3 chance Oerkki heals.
	if math.random(1, 3) > 2 then
		self.health = math.random(self.hp_min, self.hp_max)
	end

	-- Stop any current activity.
	self.attack = nil
	mobs.transition_state(self, "")
end



-- The oerkki goes to harass someone else.
local function harass(self)
	local pos = self.object:get_pos()

	-- Find a random player.
	local players = minetest.get_connected_players()
	if #players == 0 then
		return
	end
	local pref = players[math.random(1, #players)]

	local p = vector.round(pref:get_pos())

	-- Don't harass players in the city or in their bases.
	if city_block:in_city(p) or minetest.test_protection(p, "") then
		return
	end

	p.x = p.x + math.random(-10, 10)
	p.z = p.z + math.random(-10, 10)
	p.y = p.y + math.random(-15, 15)

	local minp = vector.add(p, {x=-5, y=-5, z=-5})
	local maxp = vector.add(p, {x=5, y=5, z=5})
	local targets = hb4.find_walkable_in_area_under_unwalkable(minp, maxp)
	if #targets == 0 then
		return
	end

	local target = targets[math.random(1, #targets)]
	self.object:set_pos(target)

	-- Play sound/particle effect.
	ambiance.sound_play("nether_portal_usual", pos, 1.0, 20)
	preload_tp.spawn_particles(pos)

	-- A 2/3 chance Oerkki heals.
	if math.random(1, 3) > 1 then
		self.health = math.random(self.hp_min, self.hp_max)
	end

	-- Stop any current activity.
	self.attack = nil
	mobs.transition_state(self, "")
end



-- The oerkki calls for reinforcements.
local function reinforce(self)
	local pos = self.object:get_pos()

	-- We can assume the nearest player to us is the right one.
	local pref = hb4.nearest_player(pos)
	if not pref then
		return
	end

	local p = vector.round(pref:get_pos())
	local minp = vector.add(p, {x=-5, y=-5, z=-5})
	local maxp = vector.add(p, {x=5, y=5, z=5})
	local targets = hb4.find_walkable_in_area_under_unwalkable(minp, maxp)
	if #targets == 0 then
		return
	end

	local t1 = targets[math.random(1, #targets)]
	local t2 = targets[math.random(1, #targets)]
	local t3 = targets[math.random(1, #targets)]

	-- Play sound/particle effect.
	ambiance.sound_play("teleport", pos, 1.0, 20)
	preload_tp.spawn_particles(pos)

	minetest.add_entity(t1, "griefer:griefer")
	minetest.add_entity(t2, "griefer:griefer")

	-- Small chance of a 3rd oerkki.
	if math.random(1, 3) == 1 then
		minetest.add_entity(t3, "griefer:griefer")
	end

	-- A small chance the elite oerkki despawns.
	if math.random(1, 6) == 1 then
		despawn(self)
	end

	-- A 1/3 chance Oerkki heals.
	if math.random(1, 3) > 2 then
		self.health = math.random(self.hp_min, self.hp_max)
	end
end



-- The oerkki sets up an ambush.
local function ambush(self)
	local pos = self.object:get_pos()

	local pref = hb4.nearest_player(pos)
	if not pref then
		return
	end

	local pname = pref:get_player_name()

	-- Cloak oerkki (actually we just remove it and spawn a new one later).
	cloaking.particle_effect(pos)
	self.mkrm = true

	local function spawn()
		local player = minetest.get_player_by_name(pname)
		if not player then
			return
		end

		local p = vector.round(player:get_pos())
		local minp = vector.add(p, {x=-5, y=-5, z=-5})
		local maxp = vector.add(p, {x=5, y=5, z=5})
		local targets = hb4.find_walkable_in_area_under_unwalkable(minp, maxp)
		if #targets == 0 then
			return
		end
		
		local target = targets[math.random(1, #targets)]

		-- Oerkki decloaks.
		minetest.add_entity(target, "griefer:elite_griefer")
		cloaking.particle_effect(target)
	end

	-- The oerkki reappears some time later.
	minetest.after(math.random(30, 360), spawn)
end



-- To be called externally.
function griefer.stupid_oerkki_trick(self)
	-- Choose action based on dice. Note: the ranges should not overlap, 
	-- otherwise chance percentages will be in conflict.
	local dice = math.random(1, 100)

	-- 20% chance the oerkki teleports somewhere else.
	if dice >= 80 and dice <= 100 then
		teleport(self)
		return
	end
	
	-- 10% chance the oerkki despawns.
	if dice >= 70 and dice <= 80 then
		despawn(self)
		return
	end

	-- 5% chance the oerkki teleports to somewhere the player previously was.
	if dice >= 65 and dice <= 70 then
		prevpos(self)
		return
	end

	-- 15% chance the oerkki goes to harass someone else.
	if dice >= 50 and dice <= 65 then
		harass(self)
		return
	end

	-- 10% chance the oerkki calls for reinforcements.
	if dice >= 40 and dice <= 50 then
		reinforce(self)
		return
	end

	-- 10% chance the oerkki sets up an ambush.
	if dice >= 30 and dice <= 40 then
		ambush(self)
		return
	end
end

