local YUYI_KeepOnLand = Class(function(self, inst)
    self.inst = inst
    self.inst:StartUpdatingComponent(self)
  
end)

local function setTileBlocking(block, pt)
	local ground = GetWorld()
	local px,py,pz = ground.Map:GetTileCenterPoint(pt.x, pt.y, pt.z)			
	for ix=0,1 do
		for iy =0,1 do
			local modx =-1
			local mody =-1
			if ix == 1 then
				modx = modx+2
			end
			if iy == 1 then
				mody = mody+2
			end
			ground.Flooding:SetIsPositionBlocked(px+modx,0,pz+mody, block, true)
		end
	end
end

local function setTileBlocking2(block, pt)
	local ground = GetWorld()
	local px,py,pz = ground.Map:GetTileCenterPoint(pt.x, pt.y, pt.z)			
	for ix=0,1 do
		for iy =0,1 do
			local modx =-1
			local mody =-1
			if ix == 1 then
				modx = modx+2
			end
			if iy == 1 then
				mody = mody+2
			end
			ground.Flooding:SetIsPositionBlocked(px+modx,0,pz+mody, block, false)
		end
	end
end

function YUYI_KeepOnLand:OnUpdateSw(dt)
    --local onWater = 
    local world = GetWorld()
    local function testfn(offset)
        local test_point = self.inst:GetPosition() + offset
        local tx, ty = world.Map:GetTileCoordsAtPoint(test_point.x, test_point.y, test_point.z)
		local actual_tile = world.Map:GetTile(tx, ty)
        return actual_tile ~= GROUND.YIYUA and actual_tile ~= GROUND.YIYUB and actual_tile ~= GROUND.YIYUC and actual_tile ~= GROUND.YIYU1D and actual_tile ~= GROUND.YIYU2D and actual_tile ~= GROUND.YIYU3D and actual_tile ~= GROUND.YIYU4D and actual_tile ~= GROUND.YIYU5D and actual_tile ~= GROUND.YIYU6D and actual_tile ~= GROUND.YIYU7D and actual_tile ~= GROUND.YIYU8D and actual_tile ~= GROUND.YIYU9D
	end
    if not self.inst.sg:HasStateTag("busy") and not self.inst.components.health:IsDead() then 
        local pt = self.inst:GetPosition()
		local x, y, z = self.inst.Transform:GetWorldPosition()
        local result_offset_flood = FindValidPositionByFan(0, 3, 12, testfn)
        local OnTurfs = result_offset_flood == nil
		local OnFlood = GetWorld().Flooding and GetWorld().Flooding:OnFlood( x, y, z )
		if OnTurfs then
			if OnFlood then setTileBlocking(true, pt) end
			setTileBlocking2(false, pt)
		end
	end
    if (not self.inst.components.driver or not self.inst.components.driver:GetIsDriving()) and not self.inst.sg:HasStateTag("busy") and not self.inst.components.health:IsDead() then 
		local pt = self.inst:GetPosition()
		local radius = 1 --buffer zone because the walls aren't perfecly along the visual line
		if self.inst:HasTag("yiyu_pitchfork") then radius = 4 end
		local result_offset = FindValidPositionByFan(0, radius, 12, function(offset)
            local test_point = pt + offset
            if self.inst:GetIsOnWater(test_point.x, test_point.y, test_point.z) then
                return false
            end
            return true 
        end)

        local onWater = result_offset == nil 

        if onWater and self.inst.yuyi_states ~= 1 then 
            pt = self.inst:GetPosition()
			radius = 5
            if self.inst.components.yiyucast then radius = 10 end
            result_offset = FindValidPositionByFan(0, radius, 12, function(offset)
                local test_point = pt + offset
                if self.inst:GetIsOnWater(test_point.x, test_point.y, test_point.z) then
                    return false
                end
                return true 
            end)

            if result_offset then 
                local moveto = pt + result_offset
                self.inst.Transform:SetPosition(moveto.x, moveto.y, moveto.z)
            elseif self.inst.components.health then 
                if CHEATS_ENABLED then
                    local boat = SpawnPrefab("rowboat")
                    boat.Transform:SetPosition(self.inst:GetPosition():Get())
                    self.inst.components.driver:OnMount(boat)
                else
                    self.inst.components.health:Kill("drowning")
                end
            end 
        end 
    end 
end

function YUYI_KeepOnLand:OnUpdateVolcano(dt)
    local world = GetWorld()
    local function testfn(offset)
        local test_point = self.inst:GetPosition() + offset
        local tx, ty = world.Map:GetTileCoordsAtPoint(test_point.x, test_point.y, test_point.z)
		local actual_tile = world.Map:GetTile(tx, ty)
        return actual_tile ~= GROUND.VOLCANO_LAVA
	end
    if not self.inst.sg:HasStateTag("busy") and not self.inst.components.health:IsDead() then 
        local pt = self.inst:GetPosition()
        local radius = 1.75 --buffer zone because the walls aren't perfecly along the visual line
		if self.inst:HasTag("yiyu_pitchfork") then radius = 4 end
        local result_offset = FindValidPositionByFan(0, radius, 12, testfn)
        local onLava = result_offset == nil 

        if onLava and self.inst.yuyi_states ~= 1 then
            pt = self.inst:GetPosition()
            radius = 5
            if self.inst.components.yiyucast then radius = 15 end
            result_offset = FindValidPositionByFan(0, radius, 12, testfn)

            if result_offset then 
                local moveto = pt + result_offset
                self.inst.Transform:SetPosition(moveto.x, moveto.y, moveto.z)
            elseif self.inst.components.health then 
                if not CHEATS_ENABLED then
                    self.inst.components.health:Kill("burnt")
                end
            end 
        end 
    end 
end

function YUYI_KeepOnLand:OnUpdateRog(dt)
    local world = GetWorld()
    local function testgroundfn(offset)
        local test_point = self.inst:GetPosition() + offset
        local tx, ty = world.Map:GetTileCoordsAtPoint(test_point.x, test_point.y, test_point.z)
        local actual_tile = world.Map:GetTile(tx, ty)
        return actual_tile ~= GROUND.IMPASSABLE
    end
    if not self.inst.sg:HasStateTag("busy") and not self.inst.components.health:IsDead() then 
        local pt = self.inst:GetPosition()
        local radius = 1.75 --buffer zone because the walls aren't perfecly along the visual line 
		if self.inst:HasTag("yiyu_pitchfork") then radius = 5 end
        local result_offset = FindValidPositionByFan(0, radius, 12, testgroundfn)--½Ç¶È°ë¾¶³¢ÊÔ
        local onSea = result_offset == nil 

        if onSea and self.inst.yuyi_states ~= 1 then
            pt = self.inst:GetPosition()
            radius = 10
            result_offset = FindValidPositionByFan(0, radius, 12, testgroundfn)
            if result_offset then 
                local moveto = pt + result_offset
                self.inst.Transform:SetPosition(moveto.x, moveto.y, moveto.z)
            end 
        end 
    end
end

function YUYI_KeepOnLand:OnUpdate(dt)
    local world = GetWorld()
    if world:HasTag("volcano") then
        self:OnUpdateVolcano(dt)
    elseif SaveGameIndex:IsModeShipwrecked() then
        self:OnUpdateSw(dt)
	else
		self:OnUpdateRog(dt)
    end
end


return YUYI_KeepOnLand
