require "prefabutil"

local assets=
{
	Asset("ANIM", "anim/bluebox.zip"),
	Asset("SOUNDPACKAGE", "sound/bluebox.fev"),
	Asset("SOUND", "sound/bluebox_bank00.fsb"),
	
}


local function onhammered(inst, worker)
	inst.components.lootdropper:DropLoot()
	inst.components.container:DropEverything()
	--SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_metal")
	inst:Remove()
end


local function onbuilt(inst)
	inst.AnimState:PlayAnimation("place")
	inst.AnimState:PushAnimation("closed")	
end


-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================



local function GetVerb(inst)
        return STRINGS.ACTIONS.ACTIVATE.GENERIC
end




local function getrandomposition(inst)
    local ground = GetWorld()
    local centers = {}
    for i,node in ipairs(ground.topology.nodes) do
        local tile = GetWorld().Map:GetTileAtPoint(node.x, 0, node.y)
        if tile and tile ~= GROUND.IMPASSABLE then
            table.insert(centers, {x = node.x, z = node.y})
        end
    end
    if #centers > 0 then
        local pos = centers[math.random(#centers)]
        return Point(pos.x, 0, pos.z)
    else
        return GetPlayer():GetPosition()
    end
end

local function canteleport(inst, caster, target)
      if target then
        return target.components.locomotor ~= nil
    end

    return true
end

local function teleport_thread(inst, caster, teletarget, loctarget)
    local ground = GetWorld()
    local t_loc = nil
    if loctarget then
        t_loc = loctarget:GetPosition()
    else
        t_loc = getrandomposition()
    end

    local teleportee = teletarget
    local pt = teleportee:GetPosition()
    if teleportee.components.locomotor then
        teleportee.components.locomotor:StopMoving()
    end

    if ground.topology.level_type == "cave" then
        TheCamera:Shake("FULL", 0.3, 0.02, .5, 40)
        ground.components.quaker:MiniQuake(3, 5, 1.5, teleportee)     
        return
    end

    if teleportee.components.health then
        teleportee.components.health:SetInvincible(true)
    end
    

        teleportee:Hide()



    if teleportee == GetPlayer() then
        TheFrontEnd:Fade(false, 1)                   --время затемнения перед телепортацией
        Sleep(5)                                      --время темного экрана между телепортациями
    end

   
    teleportee.Transform:SetPosition(t_loc.x, 0, t_loc.z)

    if teleportee == GetPlayer() then
        TheCamera:Snap()
        TheFrontEnd:DoFadeIn(1)                       --время осветления экрана перед появлением
        Sleep(0)                                      --время до появления персонажа
    end
    if loctarget and loctarget.onteleto then loctarget.onteleto(loctarget) end

    teleportee:Show()

    inst.components.activatable.inactive = true                      --добавленно перемещение предмета
    inst.Transform:SetPosition(t_loc.x+0.5, 0, t_loc.z+0.5)   

    if teleportee.components.health then
        teleportee.components.health:SetInvincible(false)
    end
	
    if teleportee == GetPlayer() then
        teleportee.sg:GoToState("idle")
    end
end


local function teleport_func(inst, target)
    local mindistance = 1
    local caster = GetPlayer()
    local tar = target or caster
    local pt = tar:GetPosition()
    local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 9000, {"telebase"})

    if #ents <= 0 then
        --There's no bases, active or inactive. Teleport randomly.
        inst.task = inst:StartThread(function() teleport_thread(inst, caster, tar) end)
        return
    end

    local targets = {}
    for k,v in pairs(ents) do
        local v_pt = v:GetPosition()
        if distsq(pt, v_pt) >= mindistance * mindistance then
            table.insert(targets, {base = v, distance = distsq(pt, v_pt)}) 
        end
    end

    table.sort(targets, function(a,b) return (a.distance) < (b.distance) end)
    for i = 1, #targets do
        local teletarget = targets[i]
        if teletarget.base and teletarget.base.canteleto(teletarget.base) then
            inst.task = inst:StartThread(function()  teleport_thread(inst, caster, tar, teletarget.base) end)
            return
        end
    end

    inst.task = inst:StartThread(function() teleport_thread(inst, caster, tar) end)
end

local function OnActivate(inst)
        inst.SoundEmitter:PlaySound("bluebox/untitled/event00") --добавление звука
	inst.AnimState:PlayAnimation("place", true)
print("attemp to tp")
teleport_func(inst,GetPlayer())
end

-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================
-------====================================================



local function fn(Sim)
	local inst = CreateEntity()
	inst:AddTag("structure")
        inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()

        MakeObstaclePhysics(inst, 1.5)    

	local minimap = inst.entity:AddMiniMapEntity()
	minimap:SetIcon( "bluebox.tex" )
	
    inst.AnimState:SetBank("bluebox")
    inst.AnimState:SetBuild("bluebox")
    inst.AnimState:PlayAnimation("closed", true)

    inst:AddComponent("inspectable")



    inst:AddComponent("activatable")
    inst.components.activatable.OnActivate = OnActivate
    inst.components.activatable.inactive = true
    inst.components.activatable.getverb = GetVerb
	inst.components.activatable.quickaction = false


    inst:AddComponent("lootdropper")

	local function ruinshat_proc(inst, owner)
        inst:AddTag("forcefield")
        local fx = SpawnPrefab("forcefieldfx")
        fx.entity:SetParent(inst.entity)
		GetPlayer().components.health:SetInvincible(true)
	        --inst.AnimState:PushAnimation("open")
        fx.Transform:SetPosition(0, 0, 0)
		
		local s = 2.25                           --размер поля
		fx.Transform:SetScale(s,s,s)

        local fx_hitanim = function()
            fx.AnimState:PlayAnimation("hit")
            fx.AnimState:PushAnimation("idle_loop")
        end
        fx:ListenForEvent("blocked", fx_hitanim, owner)


        inst.active = true

        owner:DoTaskInTime(--[[Duration]] TUNING.ARMOR_RUINSHAT_DURATION*2, function()
            --fx:RemoveEventCallback("blocked", fx_hitanim, owner)
            fx.kill_fx(fx)
			GetPlayer().components.health:SetInvincible(false)
            if inst:IsValid() then
                inst:RemoveTag("forcefield")
                owner:DoTaskInTime(--[[Cooldown]] 1, function() inst.active = false end)
            end
        end)
    end

    local function tryproc(inst, owner)
        if inst:GetDistanceSqToInst(GetPlayer()) < 5*5 and not inst.active and math.random() < 1 then     --радиус активации
           ruinshat_proc(inst, owner)
        end
    end


    

        inst.procfn = function() tryproc(inst,  GetPlayer()) end
        GetPlayer():ListenForEvent("attacked", inst.procfn)

    inst:ListenForEvent( "onbuilt", onbuilt)
	MakeSnowCovered(inst, .01)	
    return inst
end


return Prefab( "common/bluebox", fn, assets),
		MakePlacer("common/bluebox_placer", "bluebox", "bluebox", "closed") 

