require "class"
require "screens/pausescreen"
local cooking = require("cooking")
local easing = require "easing"
local brain = require "brains/summonclonebrain"
local brain_boat = require "brains/summonclonebrain_boat"
local k = TUNING

local trace = function() end
KEY_KP0		= 256
KEY_KP1     = 257
KEY_KP2     = 258	
KEY_KP3     = 259
KEY_KP4     = 260
KEY_KP5     = 261
KEY_KP6     = 262
KEY_KP7     = 263
KEY_KP8     = 264
KEY_KP9     = 265


-----------------------------------------------------------------------------------
--================---------------CONROLS-------------------=================--------
--=======================================================================================




-------------------------------------------------
------------------ K E Y S ------------------
------------------------------------------
local k = TUNING


k.APKEY = {}

--moving
k.APKEY["UP"] = {0, KEY_UP, KEY_I}
k.APKEY["DOWN"] = {0, KEY_DOWN, KEY_K}
k.APKEY["LEFT"] = {0, KEY_LEFT, KEY_J}
k.APKEY["RIGHT"] = {0, KEY_RIGHT, KEY_L}


--action
k.APKEY["ATTACK"] = {0, KEY_RSHIFT, KEY_U, KEY_KP8}
k.APKEY["ACTION"] = {0, KEY_RCTRL, KEY_O, KEY_KP7}


--inventory
k.APKEY["DROPALL"] ={0, KEY_PAGEUP, KEY_Y}
k.APKEY["NEXTSLOT"] = {0, KEY_HOME, KEY_RIGHTBRACKET}
k.APKEY["PREVSLOT"] = {0, KEY_INSERT, KEY_LEFTBRACKET}
k.APKEY["INVENTORYACTION"] = {0, KEY_DELETE, KEY_P}
k.APKEY["ALTACTION"] = {0, KEY_END, KEY_N}
k.APKEY["ALTACTION2"] = {0, KEY_PAGEDOWN, KEY_H}

------------------------------------------------
-------------------//keys-----------------------------------
------------------------------------------------------













--[[ How to rebind???
KEY_P2_TEST = (write here button you want to use)
example: KEY_P2_ATTACK = KEY_A
KEY_P2_ACTION = KEY_B

Do NOT use numpad! it all is used by inventory and other systems.
]]


--system
KEY_P2_TELEPORT = KEY_O   ---teleport 2 player to 1
KEY_P2_CAMERA = KEY_KP_MULTIPLY   ---bind camera to 2 player
--

--moving
KEY_P2_UP = KEY_UP
KEY_P2_LEFT = KEY_LEFT
KEY_P2_RIGHT = KEY_RIGHT
KEY_P2_DOWN = KEY_DOWN
--

--action
KEY_P2_ATTACK = KEY_RSHIFT
KEY_P2_ACTION = KEY_RCTRL  ---mine, chop, pickup etc...
KEY_P2_SPELL_CAST  = KEY_KP_PLUS --spell cast
--

--inventory
KEY_P2_DROP_ALL = KEY_PAGEUP
--

--crafting keys
KEY_P2_CRAFT_FIREPIT = KEY_END
KEY_P2_CRAFT_PICKAXE = KEY_HOME
KEY_P2_CRAFT_AXE = KEY_INSERT
KEY_P2_CRAFT_TOURCH = KEY_DELETE
--


--=======================================================================================
--================---------------CONROLS END-------------------=================--------
-----------------------------------------------------------------------------------




local prefabs =
{
    "balloon","bishop_charge","monstermeat","beemine_maxwell","shovel","spidergland","flint","ash","torch","tentaclespike","log","nitre","silk","poop","campfire","pinecone","willowfire"
}

local CameraRight = TheCamera:GetRightVec()
local CameraDown = TheCamera:GetDownVec()
--[[
local data = {{name="crawlinghorror", build = "shadow_insanity1_basic", bank = "shadowcreature1", num = 1, speed = TUNING.CRAWLINGHORROR_SPEED, health=TUNING.CRAWLINGHORROR_HEALTH, damage=TUNING.CRAWLINGHORROR_DAMAGE, attackperiod = TUNING.CRAWLINGHORROR_ATTACK_PERIOD, sanityreward = TUNING.SANITY_MED}}
]]
local function UpdateCameraHeadings()
	CameraRight = TheCamera:GetRightVec()
	CameraDown = TheCamera:GetDownVec()
end

local PlayerController_3 = Class(function(self, inst)
    self.inst = inst
    self.enabled = true
	
	self.plnum = self.inst.plnum
	local con_dis = 0
	if TUNING.CONTROLLER ~= 0 and self.plnum==2 then con_dis = 2 end
	
	
	self.thingtocraft = "axe"
    
    self.inputhandlers = {}
	
		
		---actions
		table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(k.APKEY["ATTACK"][self.plnum+con_dis], function() self:AttackActClear() end))
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["ATTACK"][self.plnum+con_dis], function() self:DoAttackButton() end))
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["ACTION"][self.plnum+con_dis], function() self:DoActionButton() end))   --- do action: mine, chop, pickup etc.  MUST BE SIMILAR
		table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(k.APKEY["ACTION"][self.plnum+con_dis], function() self:DoActionButton() end))
		
		---inventory
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["NEXTSLOT"][self.plnum], function() self:ItemInvAddNum(true) end))
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["PREVSLOT"][self.plnum], function() self:ItemInvAddNum(false) end))
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["INVENTORYACTION"][self.plnum], function() self:ItemInvUse(self.spitemnun,true) end))
		
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["DROPALL"][self.plnum], function() self:DropAll() end))    ---drop all
		
		table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["ALTACTION"][self.plnum], function() self:ItemInvDropOn() end))
		table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(k.APKEY["ALTACTION"][self.plnum], function() self:ItemInvDropOff() end))

        table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(k.APKEY["ALTACTION2"][self.plnum], function() self:ItemInvdoubleOn() end))
        table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(k.APKEY["ALTACTION2"][self.plnum], function() self:ItemInvdoubleOff() end))
		
		
		print("TUNING.CONTROLLER from playercontroller3 ======  "..TUNING.CONTROLLER)
		if TUNING.CONTROLLER == 0 then
			print("== NO COCONTOLLER DEFAULT INPUTS")
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP1, function() self:ItemInvUse(7) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP2, function() self:ItemInvUse(8) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP3, function() self:ItemInvUse(9) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP4, function() self:ItemInvUse(4) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP5, function() self:ItemInvUse(5) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP6, function() self:ItemInvUse(6) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP7, function() self:ItemInvUse(1) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP8, function() self:ItemInvUse(2) end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP9, function() self:ItemInvUse(3) end))
			
			
			
			---Actions
			--table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_P2_ATTACK, function() self:AttackActClear() end))
		--	table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_ATTACK, function() self:DoAttackButton() end))
		--	table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_ACTION, function() self:DoActionButton() end))   --- do action: mine, chop, pickup etc.  MUST BE SIMILAR
		--	table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_P2_ACTION, function() self:DoActionButton() end))
			---Actions end
		elseif con_dis>0 then
			-- KEY_P2_ATTACK = KEY_KP7
			-- KEY_P2_ACTION = KEY_KP8  ---mine, chop, pickup etc...
			print("== CONTOLLER HERE INPUTS additional craft!")
			
			---Actions
		--	table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_KP8, function() self:AttackActClear() end))
		--	table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP8, function() self:DoAttackButton() end))
		--	table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP7, function() self:DoActionButton() end))   --- do action: mine, chop, pickup etc.  MUST BE SIMILAR
		--	table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_KP7, function() self:DoActionButton() end))
			---Actions end
			
			---CRAFT
			table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP2, function() self:CraftFirepit() end))
			table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP1, function() self:CraftTorch() end))
			table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP4, function() self:CraftAxe() end))
			table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP5, function() self:CraftPickaxe() end))
			---CRAFT END
		end
		
		
	

	-----SYSTEM
    table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_KP_MINUS, function() self:DeleteWithStatsRecord(nil,nil,true) end))
	--table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_CAMERA, function() self:Camera() end))
	-----SYSTEM end
	
		
		-----NO NUMPAD!
		if TUNING.NUMPADCONROLLS==2 then
			print("NO NUMPAD")
		-- else
		-- ---CRAFT
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_CRAFT_FIREPIT, function() self:CraftFirepit() end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_CRAFT_TOURCH, function() self:CraftTorch() end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_CRAFT_AXE, function() self:CraftAxe() end))
			-- table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_P2_CRAFT_PICKAXE, function() self:CraftPickaxe() end))
		-- ---CRAFT END
		end
		---==========-INVEN END
		
		
	local desbadge = require "widgets/desbadge"
	require "prefabs/hud"
	
	local doer =GetPlayer()
	self.inst:DoTaskInTime(2,function() 
	doer.HUD.controls.desbadge = GetPlayer().HUD.controls.sidepanel:AddChild(desbadge(self.inst))
	doer.HUD.controls.desbadge:SetPosition(-200,10,0)
	--print("create des badge")
	self.desbadge=true
	doer.HUD.controls.desbadge:Hide()  
	end)
		
    self.inst:StartUpdatingComponent(self)
    self.draggingonground = false
    self.startdragtestpos = nil
    self.startdragtime = nil
	
    self.spitemnun = 1
	
	self.thingtocraft = "axe"
	self.thingstocraft={"axe","pickaxe","torch","campfire","firepit"}
	
	self.craftnum = 0
	self.specialitem = nil



	self.inventoryshown = true
	self.inventoryshownage = 0
	
end)

function PlayerController_3:Enable(val)
    self.enabled = val
end

function PlayerController_3:GiveSpecialItems()
	local function spawnspecialitem(prefabname)
		local it2 = SpawnPrefab(prefabname)
		return it2
	end

	if self.inst.specialitem and not self.inst.components.inventory:Has(self.inst.specialitem, 1) then
		self.inst:DoTaskInTime(0.1, function()	
			local item = spawnspecialitem(self.inst.specialitem)
			if not item then return end
			self.inst:DoTaskInTime(0.1, function()	
				item.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
				local action = ACTIONS.PICKUP 
				local ba = BufferedAction(self.inst, item, action)
				self.inst.components.locomotor:PushAction(ba, true)
			end)
		end)
	end
	

end









function PlayerController_3:DeleteWithStatsRecord(skipsaving,forcedelay,button,dead)

--DeleteWithStatsRecord
	local doremovedelay = false
	local allow_remove = false
	if self.inst:HasTag("DeleteWithStatsRecordDelay") and button then
					self.inst:AddTag("DeleteWithStatsRecordDelay")
					self.inst:DoTaskInTime(1, function()	
					self.inst:RemoveTag("DeleteWithStatsRecordDelay")
					return
				end)
		return
	end
	self.inst:AddTag("DeleteWithStatsRecordDelay")
	
	if not skipsaving then
			GetPlayer().components.p3stats_saver:RecordStatsSeparate(self.inst,"PlayerController_3:DeleteWithStatsRecord")			
			GetPlayer().components.p3stats_saver:RecordStats(self.inst," PlayerController_3:DeleteWithStatsRecord")
			allow_remove = true
			--doremovedelay=true
			if dead and dead == true then
				GetPlayer().components.p3stats_saver.stat["health"]=0
				GetPlayer().components.p3stats_saver.shstats[self.inst.plnum]["health"] = 0
			end

			
	end
	
	
	if self.inst.components.driver and self.inst.components.driver.driving ==true then
		--self.inst.mountedvehicle = self.inst
		self.inst.components.driver:OnDismount(nil, self.inst:GetPosition())
		doremovedelay = true
		

	end
	
	
	
	if (skipsaving and skipsaving==true) or allow_remove==true then
	
		if doremovedelay==true or forcedelay then 
			self.inst:DoTaskInTime(0.25, function()	
				self.inst.components.health:DoDelta(-10000)
				self.inst:Remove()
				return
			end)
		else
			self.inst.components.health:DoDelta(-10000)
			self.inst:Remove()
		end
		
	end


end

function PlayerController_3:Camera()
  ---  TheCamera:SetTarget(self.inst)
end



function PlayerController_3:InvOpen()

	
end
-------GetItemInSlot

function PlayerController_3:ItemInvAddNum(plus)
	if self.inst.components.health:GetPercent()<0 or self.inst.components.health:GetPercent()==0 then return end

	self.inventoryshown = true
	self.inventoryshownage = 0

	if plus==true then
		self.spitemnun = self.spitemnun+1
		self.craftnum = self.craftnum+1
	else
		self.spitemnun = self.spitemnun-1
		self.craftnum = self.craftnum-1
	end
	if self.spitemnun>19 then self.spitemnun=1
	elseif self.spitemnun<1 then self.spitemnun=19 end

	if self.craftnum>4 then self.craftnum=1
	elseif self.craftnum<1 then self.craftnum=4 end
	
	
	local newslot = self.spitemnun
	local item = self.inst.components.inventory:GetItemInSlot(self.spitemnun)
	local isequipslot = false
	if newslot ==17 then
		print("ItemInvAddNum HANDS")
		local slotitem = EQUIPSLOTS.HANDS
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	elseif newslot ==18 then
		print("ItemInvAddNum BODY")
		local slotitem = EQUIPSLOTS.BODY
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	elseif newslot ==19 then
		print("ItemInvAddNum HEAD")
		local slotitem = EQUIPSLOTS.HEAD
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	end


	
	--if self.inst.components.inventory:GetItemInSlot(self.spitemnun) then
	if self.inst:HasTag("dropinv") then
		self.inst.components.talker:ShutUp()
		self.inst.components.talker:Say("I am going to craft "..self.thingstocraft[self.craftnum]..".")
		self.inst:RemoveTag("CraftTarget")

	end
	--else
	--	self.inst.components.talker:ShutUp()
	--	self.inst.components.talker:Say(self.spitemnun..".Nothing.")
--	end
end




function PlayerController_3:ItemInvUse(data,spec)
	if self.inst:HasTag("no_actions_full_inv") then return end
local num = data
if spec == true then
num=self.spitemnun
--print("num==self.spitemnun")
else
num = data

end
if num > 19 then
num = 19

end

	local newslot = num
	local item = self.inst.components.inventory:GetItemInSlot(num)
	local isequipslot = false
	if newslot ==17 then
		local slotitem = EQUIPSLOTS.HANDS
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	elseif newslot ==18 then
		local slotitem = EQUIPSLOTS.BODY
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	elseif newslot ==19 then
		local slotitem = EQUIPSLOTS.HEAD
		item = self.inst.components.inventory.equipslots[slotitem]
		isequipslot = true
	end
	
	local chest	= FindEntity(self.inst, 1.5, function(guy) return (guy.components.container and guy.components.container.type=="chest")end)
	local pickup = FindEntity(self.inst, 1.5, function(guy) return (guy.components.fueled)end)
	local crockpot	= FindEntity(self.inst, 2, function(guy) return (guy.prefab=="cookpot")end)



	if not item then
		return
	end
	

	
	if self.inst:HasTag("dropinv") and isequipslot == false then
	  if (item.components.fuel or item.components.cookable) and pickup then
		if pickup and item.components.fuel then
		self.inst.sg:GoToState("give")
			self.inst.components.inventory:ConsumeByName(item.prefab, 1)
			local fuel = SpawnPrefab(item.prefab)
			pickup.components.fueled:TakeFuelItem(fuel)
		elseif pickup and item.components.cookable then
	---	self.inst.sg:GoToState("doshortaction")
			local cooked = item.components.cookable:Cook(self.inst)
			local pt = self.inst:GetPosition()
			cooked.Transform:SetPosition(pt.x, pt.y, pt.z)
			self.inst.components.inventory:ConsumeByName(item.prefab, 1)
			self.inst.components.talker:Say("Cooked.")
			local action = ACTIONS.PICKUP 
			local ba = BufferedAction(self.inst, cooked, action)
			self.inst.components.locomotor:PushAction(ba, true)
		end
 
	   
	  elseif chest and not chest.components.container:IsFull() then
		chest.AnimState:PlayAnimation("close") 
		chest.SoundEmitter:PlaySound("dontstarve/wilson/chest_close")		
		chest.components.container:GiveItem(item)
		print("to chest")
		
		self.inst.components.talker:Say("Go to chest.")
		self.inst.sg:GoToState("give")
		self.inst.components.inventory:RemoveItem(item,true)
	--	self.inst.components.container:RemoveItem(item,true)	
		
	  elseif crockpot and not crockpot.components.container:IsFull() and cooking.IsCookingIngredient(item.prefab) then
	  local crockpotdelete=false
  		if item.components.stackable and item.components.stackable.stacksize ==1 then
			crockpotdelete=true
			print("crockpotdelete=true")
		end
		crockpot.SoundEmitter:PlaySound("dontstarve/common/cookingpot_close", "close")
		crockpot.components.container:GiveItem(item)
		print("to crockpot")
		
		self.inst.components.talker:Say("Go to crock pot.")
		
		self.inst.sg:GoToState("give")
		if crockpotdelete==true then
			self.inst.components.inventory:RemoveItem(item,true)
			--self.inst.components.container:RemoveItem(item,true)
						print("crockpotdelete=DELETE")

		end
		
			
		if crockpot.components.stewer:CanCook() then 
			crockpot.components.stewer:StartCooking()
			self.inst.components.talker:Say("Cook it.")
		end
		
--[[]	  elseif self.inst:HasTag("pagedowntag") and item.components.deployable and item.components.deployable:CanDeploy(Vector3(self.inst:GetPosition()) then
			self.inst.components.talker:Say("Here you go.")
			local action2 = ACTIONS.DEPLOY
			local quantizedTarget = self.inst:GetPosition() 
            quantizedTarget = item.components.deployable:GetQuantizedPosition(quantizedTarget)
			local ba = BufferedAction(self.inst, nil, action2, item, quantizedTarget)
			self.inst.components.locomotor:PushAction(ba, true)--]]
      elseif not item:HasTag("specialitemplayer3") then---item
			self:DropItem(item)
	  else 
			self.inst.components.talker:Say("I can not drop this.")
	end
				
		
	else
        local actions = self.inst.components.playeractionpicker_3:GetInventoryActions(item)
		local actionnumber = 1
        if actions then
		--	if not item.components.equipbable and self.inst:HasTag("pagedowntag") then
				--actionnumber = 2
			--end
				self.inst.components.locomotor:PushAction(actions[actionnumber], true)

				local item2 = self.inst.components.inventory:GetItemInSlot(num)
				if item2 and item2.components.equipbable then
						self.inst.components.inventory:DropItem(item, true)		
						self.inst.components.inventory:RemoveItem(item,true)
				end
			
	   --  if actions[1] == ACTIONS.LOOKAT then
		 --print("look at act, for put to fire")
		-- end
		end
	end


end

function PlayerController_3:DropItem(item)
	if not item then return end
	local drop = item
	
	self.inst.components.inventory:DropItem(item, true)		
	self.inst.components.inventory:RemoveItem(item,true)
end

function PlayerController_3:DropInventory(onlyequip,keepeq)
    self.inst:StartThread(function()
        for k = 0, 19 do

			local newslot = k
			local item = self.inst.components.inventory:GetItemInSlot(newslot)
			local isequipslot = false
			if newslot ==17 then
				local slotitem = EQUIPSLOTS.HANDS
				item = self.inst.components.inventory.equipslots[slotitem]
				isequipslot = true
			elseif newslot ==18 then
				local slotitem = EQUIPSLOTS.BODY
				item = self.inst.components.inventory.equipslots[slotitem]
				isequipslot = true
			elseif newslot ==19 then
				local slotitem = EQUIPSLOTS.HEAD
				item = self.inst.components.inventory.equipslots[slotitem]
				isequipslot = true
			end
			if onlyequip and isequipslot==true then return end
			if item and isequipslot==false then 
				self:DropItem(item)
			elseif item and keepeq and isequipslot==true then
				print("DROP KEEP EQUIP")
			end
            --Sleep(math.random( .3, .5))
        end
    end)

end




function PlayerController_3:ItemInvDropOn()
local desbadge = require "widgets/desbadge"
require "prefabs/hud"
	local doer = GetPlayer()

		print("show des badge")
		if doer.HUD and self.desbsh ==false then
			doer.HUD.controls.desbadge:Show()
			self.desbsh =true
		end
	---end




if not self.inst:HasTag("dropinv") then
    self.inst:AddTag("dropinv")
end

end


local function finditeminchest(chest, slotnum)
	local slot = slotnum
	if slotnum>6 then return false end
	local item = chest.components.container:GetItemInSlot(slotnum)
	if not item then
		print("circle: "..slot)
		local c = slot+1
		finditeminchest(chest, c)
	else
		print("on circle: "..slot)
		print(item.prefab)
		return item
	end
end

function PlayerController_3:TakeItemFromChest()
		local player1near	= FindEntity(self.inst, 1, function(guy) return (guy==GetPlayer())end)
		local chest	= FindEntity(self.inst, 1.5, function(guy) return ((guy.components.container and guy.components.container.type=="chest") or (guy.prefab=="cookpot"))end)
	---	local crockpot	= FindEntity(self.inst, 2, function(guy) return end)
		
		if chest then
			---local item = finditeminchest(chest, 1)
			
			
				---print("to drop: "..item.prefab)
				chest.AnimState:PlayAnimation("close") 
				chest.SoundEmitter:PlaySound("dontstarve/wilson/chest_close")		
				chest.components.container:DropEverything()
				self.inst.components.talker:Say("Get out of store.")
		end
end



function PlayerController_3:ItemInvDropOff()
local desbadge = require "widgets/desbadge"
require "prefabs/hud"

	local doer = GetPlayer()

	if doer.HUD and self.desbadge==true then
		print("hide des badge")
		doer.HUD.controls.desbadge:Hide()
		self.desbsh =false
	end

if self.inst:HasTag("dropinv") then
    self.inst:RemoveTag("dropinv")
end
end

function PlayerController_3:ItemInvdoubleOn()
if not self.inst:HasTag("pagedowntag") then
    self.inst:AddTag("pagedowntag")
end
end

function PlayerController_3:ItemInvdoubleOff()
if self.inst:HasTag("pagedowntag") then
    self.inst:RemoveTag("pagedowntag")
end
end


function PlayerController_3:DropAll()
	if self.inst:HasTag("dropinv") then
		self:DropInventory(true)
	else
		self:DropInventory()

	end
end




----==============LOCAL============--------------


local function SpawnEffect(inst)
    local pt = inst:GetPosition()
    local fx = SpawnPrefab("small_puff")
    fx.Transform:SetPosition(pt.x, pt.y, pt.z)
    fx.Transform:SetScale(0.5,0.5,0.5)
end

local function SpawnEffect2(inst)
    local pt = inst:GetPosition()
    local fx = SpawnPrefab("small_puff")
    fx.Transform:SetPosition(pt.x, pt.y, pt.z)
    fx.Transform:SetScale(0.9,0.9,0.9)
end


local function getitem(self, item)
    --Amulet will only ever pick up items one at a time. Even from stacks.
    if item.components.stackable then
        item = item.components.stackable:Get()
    end
	SpawnEffect(item)

   --self.inst.components.container:GiveItem(item)
end



local function finddrivernear(inst, dist)

	local rad = dist or 5
	
	
	
	local other	= FindEntity(inst, rad, function(guy) return (guy.components.driver and guy.components.driver:GetIsDriving() and guy.plnum==1) end)
	if not other then
		other = FindEntity(inst, rad, function(guy) return (guy.components.driver and guy.components.driver:GetIsDriving() and guy.plnum~=inst.plnum) end)
	end
	
	
	return other
end



local function FindLand(player2,dist,step, angle, needsboat)
	local angleold = angle or -0.1
	local anglenew = angleold+0.1
	local nextstep = step +1
    local dst = dist+.25
	local radius1 = dst
	local theta = anglenew*2*PI
	local offset = Vector3(radius1 * math.cos( theta ), 0, -radius1 * math.sin( theta ) )
	
	
	
	local pt = player2:GetPosition()
    local radius = 1 --buffer zone because the walls aren't perfecly along the visual line 
    local result_offset = FindValidPositionByFan(0, radius, dst, function(offset)
    local test_point = pt + offset
        if player2:GetIsOnWater(test_point.x, test_point.y, test_point.z) then
            return false
        end
        return true 
    end)
	
        local onWater = result_offset == nil 

        if onWater then 
            pt = player2:GetPosition()
            radius = 5 
            result_offset = FindValidPositionByFan(0, radius, dst, function(offset)
                local test_point = pt + offset
                if player2: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
				return moveto
			elseif nextstep<11 then
				print("NEXT STEP")
				return FindLand(player2,dst,nextstep, nil, needsboat)
			
			else
				return nil
			end
        end 
	

end


----==============LOCAL end============--------------





------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------- CRAFT------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------		self.thingstocraft={"axe","pickaxe","torch","campfire","firepit"}

function PlayerController_3:CraftTarget()
	if self.inst:HasTag("CraftTarget") then
					self.inst:DoTaskInTime(2, function()	
					self.inst:RemoveTag("CraftTarget")
					return
				end)
	end
	if self.inst:HasTag("CraftTarget") then print("ALREADY CRAFTING") return end
	self.inst:AddTag("CraftTarget")

	
	print("PlayerController_3:CraftTarget")
	local craftnum = self.craftnum or 1
	if craftnum == 1 then
		self:CraftAxe()
	elseif craftnum == 2 then
		self:CraftPickaxe()
	
	elseif craftnum == 3 then
		self:CraftTorch()
	
	elseif craftnum == 4 then
		self:CraftFirepit()
	end
end


function PlayerController_3:CraftAxe()
    if self.inst.components.inventory:Has("flint", 1) and self.inst.components.inventory:Has("twigs", 1) then
    local rabbit = SpawnPrefab("axe")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("flint", 1)
    self.inst.components.inventory:ConsumeByName("twigs", 1)
	SpawnEffect(rabbit)
	local action = ACTIONS.PICKUP 
	local ba = BufferedAction(self.inst, rabbit, action)
	self.inst.components.locomotor:PushAction(ba, true)
end
end



function PlayerController_3:CraftPickaxe()
    if self.inst.components.inventory:Has("flint", 2) and self.inst.components.inventory:Has("twigs", 1) then
    local rabbit = SpawnPrefab("pickaxe")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("flint", 2)
    self.inst.components.inventory:ConsumeByName("twigs", 1)
	SpawnEffect(rabbit)
	local action = ACTIONS.PICKUP 
	local ba = BufferedAction(self.inst, rabbit, action)
	self.inst.components.locomotor:PushAction(ba, true)
end
end

function PlayerController_3:CraftTorch()
    if self.inst.components.inventory:Has("cutgrass", 2) and self.inst.components.inventory:Has("twigs", 1) then
    local rabbit = SpawnPrefab("torch")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("cutgrass", 2)
    self.inst.components.inventory:ConsumeByName("twigs", 1)
	SpawnEffect(rabbit)
	local action = ACTIONS.PICKUP 
	local ba = BufferedAction(self.inst, rabbit, action)
	self.inst.components.locomotor:PushAction(ba, true)
end
end


function PlayerController_3:CraftFirepit()
------------------------------------------------------------
--------//// BOATING block this action while at sea///////----------
	if	self.inst.boatingwith ~=0 then
		self.inst.components.talker:Say("Can't craft that in sea.")
		return
	end
--------//// BOATING block action end///////----------
------------------------------------------------------------
    if self.inst.components.inventory:Has("log", 2) and self.inst.components.inventory:Has("cutgrass", 3) then
    local rabbit = SpawnPrefab("campfire")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("log", 2)
    self.inst.components.inventory:ConsumeByName("cutgrass", 3)
end
end




function PlayerController_3:EatCraft()
    if self.inst.components.inventory:Has("log", 2) and self.inst.components.inventory:Has("cutgrass", 1) then
    self.inst.components.hunger:DoDelta(target.components.edible:GetHunger(target))
	SpawnEffect(target)
	target:Remove()
    self.inst.components.inventory:ConsumeByName(target, 1)
end
end





function PlayerController_3:CraftTrap()
------------------------------------------------------------
--------//// BOATING block this action while at sea///////----------
	if	self.inst.boatingwith == 1 then
		self.inst.components.talker:Say("Can't do that in sea.")
		return
	end
--------//// BOATING block action end///////----------
------------------------------------------------------------
    if self.inst.components.inventory:Has("cutgrass", 1) and self.inst.components.inventory:Has("twigs", 1) then
    local rabbit = SpawnPrefab("trap")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("cutgrass", 1)
    self.inst.components.inventory:ConsumeByName("twigs", 1)
    rabbit.components.finiteuses:SetMaxUses(5)
    rabbit.components.finiteuses:SetUses(5)
	SpawnEffect(rabbit)
end
end






function PlayerController_3:CraftStone()
    if self.inst.components.inventory:Has("flint", 6) and self.inst.components.inventory:Has("ash", 3) then
    local rabbit = SpawnPrefab("heatrock")
    rabbit.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("flint", 6)
    self.inst.components.inventory:ConsumeByName("ash", 3)
	SpawnEffect(rabbit)
end
end

function PlayerController_3:TP()


    local player2 = self.inst
	local player1 = GetPlayer()
    if (player1:GetDistanceSqToInst(player2) > (10*10)) then


	local pt = player1:GetPosition()
    local pt2 = player2:GetPosition()

     player2.Transform:SetPosition(pt.x, pt.y, pt.z)
     end
end

function PlayerController_3:Open()
   --- self.inst.components.container:Open(self)
end



-------------------------------------------------------------------------------------
----------------------------   CRAFT end
-------------------------------------------------------------------------------------

---ORANGE



function PlayerController_3:Pick()
    local pt = self.inst:GetPosition()
    local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, 1.5)
	local eater = self
	
    for k,v in pairs(ents) do
        if v.components.inventoryitem and v.components.inventoryitem.canbepickedup and v.components.inventoryitem.cangoincontainer and not
            v.components.inventoryitem:IsHeld() then
            if not self.inst.components.inventory:IsFull() then
                --Your inventory isn't full, you can pick something up.
                getitem(self, v)
                return

            elseif v.components.stackable then
                --Your inventory is full, but the item you're trying to pick up stacks. Check for an exsisting stack.
                --An acceptable stack should: Be of the same item type, not be full already and not be in the "active item" slot of inventory.
                local stack = self.inst.components.inventory:FindItem(function(item) return (item.prefab == v.prefab and not item.components.stackable:IsFull()
                    and item ~= self.inst.components.inventory.activeitem) end)
                if stack then
                    getitem(self, v)
                    return
                end
            end
end
end
end

function PlayerController_3:IsReallyBoating()
	local isboating = false
	if not self.inst.components.driver then return false end
    if self.inst.boatingwith ~= 0 and self.inst.boatingwith ~= 4 then --------- or self.inst.boatingwith == 3 then 
		local other	= finddrivernear(self.inst, 2)---FindEntity(self.inst, 2, function(guy) return (guy.prefab==GetPlayer().prefab) end)
		if other then
			self.inst.startupdatingboatwithplayer = true
			self.inst:AddTag("aquatic")
			print("IsReallyBoating with "..other.prefab)
			isboating=true
		end
	elseif self.inst.components.driver.driving == true then
		print("IsReallyBoating alone")
		print("Correctiong boatingwith=2")
		self.inst.boatingwith = 4
		self.inst.startupdatingboatwithplayer = false
		isboating=true
	end
	return isboating
end



function PlayerController_3:OnUpdate(dt)
	if self.inventoryshown==true then
		self.inventoryshownage = self.inventoryshownage+dt
		if self.inventoryshownage>20 then
			self.inventoryshown = false
		end 
	end
	
    if self.inst.components.health.currenthealth <= 0 then
		self:DropInventory()
		return
	end
	
	if self.enabled ==false then
		return
	end
-----------------------------
----------------------------------------------------------
---///Sailing position///---

	--if self.inst.boatingwith == 1 and GetPlayer().components.driver.driving==false then
--			self.inst:SetStateGraph("SGcloneplayer")
	--		self:UnMountBoat()
	--		return
	--end

    if self.inst.boatingwith ~=0 and self.inst.boatingwith ~=4 and self.inst.startupdatingboatwithplayer == true then 
		if GetPlayer().components.driver.driving==false then
			--self.inst:SetStateGraph("SGcloneplayer")
			self:UnMountBoat(true)
			return
		end
    	local myPos = GetPlayer():GetPosition()
		
		local CameraRight = TheCamera:GetRightVec()
        local CameraDown = TheCamera:GetDownVec()
        
        local displacement = CameraRight:Cross(CameraDown) * 0.2

        local pos = myPos + displacement*1.15 --Move the player slightly closer to the camera so they draw on top of the boat
									--2  3 
		local displace_xz = 0.6+(self.inst.plnum-2)*0.1
		local heading_angle = -(GetPlayer().Transform:GetRotation())
		local dir = Vector3(math.cos(heading_angle*DEGREES),0, math.sin(heading_angle*DEGREES))
		
		self.inst.Transform:SetPosition(pos.x-dir.x*displace_xz , pos.y, pos.z-dir.z*displace_xz)


		
		--return
    end
	
	
	self:UpdateControllerAttackTarget()

	
	
	--if self.inst.boatingwith == 1 then return end
---///sailing position end///---
----------------------------------------------------------
-----------------------------

--	if self.inst:HasTag("moveblocked") then return end
	
	
	local boatdifuser = 1
	if self.inst.boatingwith == 1 then
		boatdifuser = 10000
	
	
	end
	
	
	if not self.inst.sg:HasStateTag("busy") then
		if self.startdragtime then
			local pt = TheInput:GetMouseWorldPos()
			local dst = distsq(pt, Vector3(self.inst.Transform:GetWorldPosition()))
			if dst > 1 then
				local angle = self.inst:GetAngleToPoint(pt)
				self.inst.components.locomotor:RunInDirection(angle)
				self.inst:ClearBufferedAction()
			end
			self.directwalking = false
		else
	        
			--WASD walking!
			local xwalk = 0
			local ywalk = 0
			
			if TheInput:IsKeyDown(k.APKEY["UP"][self.plnum]) then
			--if TheInput:IsKeyDown(k.APKEY_UP[self.plnum]) then
				ywalk = ywalk + 1
				self.inst:ClearBufferedAction()

			end

			if TheInput:IsKeyDown(k.APKEY["DOWN"][self.plnum]) then
				ywalk = ywalk - 1
				self.inst:ClearBufferedAction()
			end

			if TheInput:IsKeyDown(k.APKEY["LEFT"][self.plnum]) then
				xwalk = xwalk - 1
				self.inst:ClearBufferedAction()
			end
	        
			if TheInput:IsKeyDown(k.APKEY["RIGHT"][self.plnum]) then
				xwalk = xwalk + 1
				self.inst:ClearBufferedAction()
			end
	        
			if not 	TheInput:IsKeyDown(k.APKEY["UP"][self.plnum]) and not
					TheInput:IsKeyDown(k.APKEY["DOWN"][self.plnum]) and not
					TheInput:IsKeyDown(k.APKEY["LEFT"][self.plnum]) and not
					TheInput:IsKeyDown(k.APKEY["RIGHT"][self.plnum]) then

					
					CameraRight = TheCamera:GetRightVec()
					CameraDown = TheCamera:GetDownVec()
			end
			
			if xwalk ~= 0 or ywalk ~= 0 then
     			local dir = CameraRight * xwalk / boatdifuser - CameraDown * ywalk / boatdifuser
				dir = dir:GetNormalized()
				local ang = -math.atan2(dir.z, dir.x)/DEGREES
				self.inst.components.locomotor:WalkInDirection(ang, true)
				self.directwalking = true
				self.inst.components.locomotor:SetBufferedAction(nil)
				self.inst:ClearBufferedAction()
				
				if not self.inst.sg:HasStateTag("attack") then
					self.inst.components.combat:SetTarget(nil)
				end
			else
				if self.directwalking then
					self.inst.components.locomotor:Stop()
					self.directwalking = false
				end
            end
		end
    end
    
end






function PlayerController_3:GetActionButtonAction()
	if self.inst:HasTag("no_actions_full_inv") then
	 print("no_actions_full_inv")
	
		return nil
	end

	local chancedisplace = 0.4

	if self.actionbuttonoverride then
		return self.actionbuttonoverride(self.inst)
	end
		local tool = self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
	if not (self.inst.sg:HasStateTag("working") or self.inst.sg:HasStateTag("doing"))
	or ((tool and tool.components.tool and (tool.components.tool:CanDoAction(ACTIONS.CHOP) or tool.components.tool:CanDoAction(ACTIONS.MINE))) and math.random()<chancedisplace) then

		tool = self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)

		--bug catching (has to go before combat)
		if tool and tool.components.tool and tool.components.tool:CanDoAction(ACTIONS.NET) then
			local target = FindEntity(self.inst, 5, 
				function(guy) 
					return  guy.components.health and not guy.components.health:IsDead() and 
							guy.components.workable and
							guy.components.workable.action == ACTIONS.NET
				end)
			if target then
			    return BufferedAction(self.inst, target, ACTIONS.NET, tool)
			end
		end
			
		
		--catching
		local rad = 8
		local projectile = FindEntity(self.inst, rad, function(guy)
		    return guy.components.projectile
		           and guy.components.projectile:IsThrown()
		           and self.inst.components.catcher
		           and self.inst.components.catcher:CanCatch()
		end)
		if projectile then
			return BufferedAction(self.inst, projectile, ACTIONS.CATCH)
		end
		
		rad = self.directwalking and 3 or 6
		if self.inst.boatingwith==1 then rad = 4 end
		--pickup
		local pickup = FindEntity(self.inst, rad, function(guy) return (guy.components.inventoryitem and guy.components.inventoryitem.canbepickedup) or
																		(tool and tool.components.tool and guy.components.workable and tool.components.tool:CanDoAction(guy.components.workable.action)) or
																		(guy.components.pickable and guy.components.pickable:CanBePicked() and guy.components.pickable.caninteractwith) or
																		(guy.components.stewer and guy.components.stewer.done) or
																		(guy.components.crop and guy.components.crop:IsReadyForHarvest()) or
																		(guy.components.harvestable and guy.components.harvestable:CanBeHarvested()) or
																		(guy.components.trap and guy.components.trap.issprung) or
																		(guy.components.dryer and guy.components.dryer:IsDone()) or
																		(guy.components.activatable and guy.components.activatable.inactive) or
																		(tool and tool.components.tool and guy.components.hackable  and guy.components.hackable:CanBeHacked() and tool.components.tool:CanDoAction(ACTIONS.HACK))
																		 end)

		local has_active_item = self.inst.components.inventory:GetActiveItem() ~= nil
		if pickup and not has_active_item then
			local action = nil
			
			if (tool and tool.components.tool and pickup.components.workable and tool.components.tool:CanDoAction(pickup.components.workable.action)) then
				action = pickup.components.workable.action
			elseif pickup.components.trap and pickup.components.trap.issprung then
				action = ACTIONS.CHECKTRAP
			elseif pickup.components.activatable and pickup.components.activatable.inactive then
				action = ACTIONS.ACTIVATE
			elseif pickup.components.inventoryitem and pickup.components.inventoryitem.canbepickedup then 
				action = ACTIONS.PICKUP 
			elseif pickup.components.pickable and pickup.components.pickable:CanBePicked() then 
				action = ACTIONS.PICK 
			elseif pickup.components.harvestable and pickup.components.harvestable:CanBeHarvested() then
				action = ACTIONS.HARVEST
			elseif pickup.components.crop and pickup.components.crop:IsReadyForHarvest() then
				action = ACTIONS.HARVEST
			elseif pickup.components.dryer and pickup.components.dryer:IsDone() then
				action = ACTIONS.HARVEST
			elseif pickup.components.stewer and pickup.components.stewer.done then
				action = ACTIONS.HARVEST
			elseif (tool and tool.components.tool and pickup.components.hackable  and pickup.components.hackable:CanBeHacked() and tool.components.tool:CanDoAction(ACTIONS.HACK)) then
				action = ACTIONS.HACK
			end
			
			if action then
			
			
			
			    local ba = BufferedAction(self.inst, pickup, action, tool)
			    --ba.distance = self.directwalking and rad or 1
			    return ba
			end
		end
	end	
end





function PlayerController_3:DoActionButton()

------////////////////CRAFT/////////-------------
	if self.inst:HasTag("dropinv") then
		self:CraftTarget()

		return
	end
--------------------end CRAFT/----------------------------------------


-----//////////////////BOATING-------------------------
	if self.inst:HasTag("CheckingSailor") then
		print("=====LOOKING FOR BOAT====")

		local getplayer = GetPlayer()
		local player1near	= FindEntity(self.inst, 5, function(guy) return (guy.prefab==getplayer.prefab) end)
		local player2 = self.inst
		
		local other = finddrivernear(self.inst)
		
		local isboating = player2.components.playercontroller_3:IsReallyBoating()
		if isboating==false and player2.boatingwith ~=0 then
			print("PlayerController_3:DoActionButton()")
			print("isboating==false")
			print("CORRECRING")

			--player2:AddComponent("Player3KeepOnLand")
			player2.boatingwith =0
			player2.startupdatingboatwithplayer = true
			
			ChangeToCharacterPhysics(player2)
			player2.Physics:SetActive(true)
			
			player2:RemoveTag("UnMountBoat")
			player2:RemoveTag("CheckingSailor")

		end
		--if player1near ~= nil then print("=========================PLAYER 1 ON BOAT FOUND==========") end
				
		if  self.inst.boatingwith ~= 0 then self:UnMountBoat() return end
		
		if getplayer.components.driver and getplayer.components.driver.driving==true and self.inst.boatingwith == 0
		and other ~= nil then
			print("boat found")
			self.inst.mountedvehicle = other.components.driver.vehicle
			self.inst.startupdatingboatwithplayer = false
			self:MountBoat(other)
			return
		end
		
		
		local emptyboatnear	= FindEntity(self.inst, 4, function(guy) return (guy.components.drivable and not guy:HasTag("NOCLICK") and guy.components.boathealth and not guy.components.boathealth:IsDead()) end)
		if emptyboatnear and self.inst.boatingwith == 0  then
			self:MountEmptyBoat(emptyboatnear)
			return
		end--]]
		
		
		if self.inst.boatingwith == 4 and self.inst.components.driver.driving == true then
			self.inst.startupdatingboatwithplayer = false
			self:UnMountBoat()
			return
		end
		
		return
	end
-----//////////////////end BOATING-------------------------




------------------------------------------------------------
--------//// BOATING block this action while at sea///////----------
	--if	self.inst.boatingwith == 1 then
	--	self.inst.components.talker:Say("Can't do that in sea.")
--		return
--	end
--------//// BOATING block action end///////----------
------------------------------------------------------------






	--do the placement
	if self.placer then
		if self.placer.components.placer.can_build then
			self.inst.components.builder:MakeRecipe(self.placer_recipe, Vector3(self.placer.Transform:GetWorldPosition()))
			return true
		end
	else
		local ba = self:GetActionButtonAction()
		if ba then
			self.inst.components.locomotor:PushAction(ba, true)
		end
		return true
	end
end

function PlayerController_3:DoInspectButton()
	if self.controller_target and GetPlayer():CanExamine() then
		self.inst.components.locomotor:PushAction( BufferedAction(self.inst, self.controller_target, ACTIONS.LOOKAT))
	end
	return true
end






--------========ATTACK=======-------------

function PlayerController_3:GetAttackTarget()
if not self.inst:HasTag("attackest1") then

    local pt = self.inst:GetPosition()

	
	--To deal with entity collision boxes we need to pad the radius.
	local nearby_ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 10)
	local tool = self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
	local has_weapon = tool and tool.components.weapon 
	
	local playerRad = self.inst.Physics:GetRadius()
	
	for k,guy in ipairs(nearby_ents) do

		if guy ~= self.inst and
		   guy:IsValid() and 
		   not guy:IsInLimbo() and
		   not (guy.sg and guy.sg:HasStateTag("invisible")) and
		   guy.components.health and not guy.components.health:IsDead() and 
		   guy.components.combat and guy.components.combat:CanBeAttacked(self.inst) and
		   not (guy.components.follower and guy.components.follower.leader == self.inst) and
		   --Now we ensure the target is in range.
		   distsq(guy:GetPosition(), self.inst:GetPosition()) <= math.pow(10 + guy.Physics:GetRadius() + 0.1 , 2) then
				if not guy:HasTag("player") and not guy:HasTag("playerfriends") and not guy:HasTag("abigail") then
		local action = BufferedAction(self.inst, guy, ACTIONS.ATTACK)
                self.inst.components.combat:DoAttack(guy, nil, nil)
				                self.inst.sg:GoToState("attack")

    self.inst:AddTag("attackest1")
	self.inst:DoTaskInTime(1, function() 
    self.inst:RemoveTag("attackest1")
    end)

						return guy
				end
		end
	end
end
end

function PlayerController_3:DoAttackButton()

	if not self.inst:HasTag("CheckingSailor") then
		--print("PlayerController_3:DoAttackButton() addinh tag CheckingSailor")

		self.inst:AddTag("CheckingSailor")
			self.inst:DoTaskInTime(1, function()	
			self.inst:RemoveTag("CheckingSailor")
			--print("PlayerController_3:DoAttackButton() removing tag CheckingSailor")
		end)
	end
	

	if self.inst:HasTag("dropinv") then
		self:TakeItemFromChest()
		return
	end



	self:DoControllerAttack()
	
	--[[
	local attack_target = self:GetAttackTarget() 			
	if attack_target and self.inst.components.combat.target ~= attack_target then
		local action = BufferedAction(self.inst, attack_target, ACTIONS.ATTACK)
		self.inst.components.locomotor:PushAction(action, true)
	else
		return -- already doing it!
	end--]]
	

end



function PlayerController_3:AttackAct5()

		local rad = 10
		local target = FindEntity(self.inst, rad, function(guy) return guy.components.health and not guy.components.health:IsDead() and guy.components.combat and not (guy.components.follower and guy.components.follower.leader == self.inst) end)
		if target then
		    self.inst:AddTag("attackest")
			local can_attack = target:HasTag("player") or target.components.combat.target == self.inst
			if not can_attack then
				local action = BufferedAction(self.inst, target, ACTIONS.ATTACK)
				self.inst:ClearBufferedAction()
                self.inst.components.combat:SetTarget(target)
                self.inst.components.combat:DoAttack(target, nil, nil)
				self.inst.components.locomotor:PushAction(action, true)
				return
			end
		end
end

function PlayerController_3:AttackActClear()
    self.inst:RemoveTag("attackest")
	self.inst:RemoveTag("controller_attaking")
--[[
        self.inst.components.locomotor:Clear()
		local target = nil
        self.inst.components.combat:GiveUp()
		--]]
end

function PlayerController_3:AttackAct6()
	local action = self:AttackAct5()
	if action then
	self.inst.components.locomotor:PushAction(action, true)	
	end
	return true
end



local must_have_attack ={"HASCOMBATCOMPONENT"}
local cant_have_attack ={"FX", "NOCLICK", "DECOR", "INLIMBO"}

function PlayerController_3:DoControllerAttack()
	self.time_direct_walking = 0

	local attack_target = self.controller_attack_target

	---bonus attack range if is boating as passenger
	if self.inst.startupdatingboatwithplayer==true then
		self.inst.components.combat.attackrange = 3 + 2
	else
		self.inst.components.combat.attackrange = 3
	end
	
	
	if attack_target and self.inst.components.combat.target ~= attack_target then
		local action = BufferedAction(self.inst, attack_target, ACTIONS.ATTACK)
		self.inst.components.locomotor:PushAction(action, true)
		self.inst:AddTag("controller_attaking")
	elseif not attack_target and not self.inst.components.combat.target then

		local action = BufferedAction(self.inst, nil, ACTIONS.FORCEATTACK)
		self.inst.components.locomotor:PushAction(action, true)
		self.inst:AddTag("controller_attaking")
	else

		return -- already doing it!
	end
end

function PlayerController_3:CanAttackWithController(target)
	return target ~= self.inst and
			target:IsValid() and 
			(target.components.health and target.components.health.currenthealth > 0) and
			not target:IsInLimbo() and
			not target:HasTag("wall") and
			not target:HasTag("player_coop_team") and
			not (target.sg and target.sg:HasStateTag("invisible")) and
			target.components.health and not target.components.health:IsDead() and 
			target.components.combat and target.components.combat:CanBeAttacked(self.inst)
end

function PlayerController_3:UpdateControllerAttackTarget(dt)
--	if self.controllerattacktargetage then
	--	self.controllerattacktargetage = self.controllerattacktargetage + dt
	--end
	
	--if self.controller_attack_target and self.controllerattacktargetage and self.controllerattacktargetage < .3 then return end

	local heading_angle = -(self.inst.Transform:GetRotation())
	local dir = Vector3(math.cos(heading_angle*DEGREES),0, math.sin(heading_angle*DEGREES))
	
	local me_pos = Vector3(self.inst.Transform:GetWorldPosition())
	
	
	local min_rad = 4
	local max_range = self.inst.components.combat:GetAttackRange() + 3

	local rad = 8
	if self.controller_attack_target and self.controller_attack_target:IsValid() and self:CanAttackWithController(self.controller_attack_target) then
		local distsq = self.inst:GetDistanceSqToInst(self.controller_attack_target)
		if distsq <= max_range*max_range then
			rad = math.min(rad, math.sqrt(distsq) * .5)
		end
	end
	
	local x,y,z = me_pos:Get()
	local nearby_ents = TheSim:FindEntities(x,y,z, rad, must_have_attack, cant_have_attack)

	local target = nil
	local target_score = nil
	local target_action = nil

	if self.controller_attack_target then
		table.insert(nearby_ents, self.controller_attack_target)
	end

	for k,v in pairs(nearby_ents) do
	
		local canattack = self:CanAttackWithController(v)

		if canattack then

			local px,py,pz = v.Transform:GetWorldPosition()
			local ox,oy,oz = px - me_pos.x, py - me_pos.y, pz - me_pos.z
			local dsq = ox*ox + oy*oy +oz*oz
			local dist = dsq > 0 and math.sqrt(dsq) or 0
			
			local dot = 0
			if dist > 0 then
				local nx, ny, nz = ox/dist, oy/dist, oz/dist
				dot = nx*dir.x + ny*dir.y + nz*dir.z
			end
			
			if (dist < min_rad or dot > 0) and dist < max_range then
				
				local score = (1 + dot)* (1 / math.max(min_rad*min_rad, dsq))

				if (v.components.follower and v.components.follower.leader == self.inst) or self.inst.components.combat:IsAlly(v) then
					score = score * .25
				elseif v:HasTag("monster") then
					score = score * 4
				end

				if v.components.combat.target == self.inst then
					score = score * 6
				end

				if self.controller_attack_target == v then
					score = score * 10
				end

				if not target or target_score < score then
					target = v
					target_score = score
				end
			end
		end
	end

	if not target and self.controller_target and self.controller_target:HasTag("wall") and self.controller_target.components.health and self.controller_target.components.health.currenthealth > 0 then
		target = self.controller_target
	end

	if target ~= self.controller_attack_target then
		self.controller_attack_target = target
	--	self.controllerattacktargetage = 0
	end
	
	

end


--------========ATTACK END=======-------------






--------========BOAT========------------

function PlayerController_3:MountEmptyBoat(emptyboatnear, range, called)
	--if self.inst.plnum==3 then self:MountBoat() return end
	local rad = range or 4
	local boat = emptyboatnear or FindEntity(self.inst, rad, function(guy) return (guy.components.drivable and not guy.components.drivable.driver and guy.components.boathealth and not guy.components.boathealth:IsDead()) end)
		

	if not boat and not called then
		self:MountBoat()
		return
	end
	--self.inst:RemoveComponent("Player3KeepOnLand")
		
	self.inst.startupdatingboatwithplayer = false
	local action = ACTIONS.MOUNT
	local ba = BufferedAction(self.inst, boat, action)
	self.inst.mountedvehicle = boat
	self.inst.components.locomotor:PushAction(ba, true)
	self.inst.boatingwith = 4
	
			
end



function PlayerController_3:MountBoat(other)
	print("=====================MountBoat==================")
	local inst = self.inst
	if self.inst:HasTag("MountBoat") then return end
	self.inst:AddTag("MountBoat")
	self.inst:DoTaskInTime(1, function()	
    self.inst:RemoveTag("MountBoat")
	self.inst:RemoveTag("CheckingSailor")
    end) 
	if not other then other = finddrivernear(self.inst) end
	if not other then self:MountEmptyBoat(nil, nil, true) return end
	--self.inst:RemoveComponent("Player3KeepOnLand")

	self.inst.boatingwith = other.plnum
	self.inst.mountedvehicle = other.components.driver.vehicle
	
	self.inst:RemoveTag("UnMountBoat")
  
	self.inst:RemoveTag("CheckingSailor")
    self.inst.Physics:ClearCollisionMask()
   -- self.inst.Physics:CollidesWith(COLLISION.CHARACTERS)
    self.inst.Physics:CollidesWith(COLLISION.GROUND)
	self.inst.Physics:SetActive(true)
	

	
	self.inst.components.moisture.baseDryingRate = 0.25

	
	local pt = self.inst.mountedvehicle:GetPosition()
	self.inst.sg:GoToState("player3jumpstart", pt)
	
	self.inst.components.playercontroller_3:Enable(false)
	
	self.inst:DoTaskInTime(18 / 30, function()	
		self.inst.startupdatingboatwithplayer = true
		self.inst.boatingwith = other.plnum
		
		self.inst:AddTag("aquatic")

		self.inst.components.playercontroller_3:Enable(true)

		--self.inst.Transform:SetPosition(GetPlayer().Transform:GetWorldPosition())
		self.inst.components.activatable.inactive = nil
	--	self.inst.components.locomotor.runspeed = 6.25+0.75
	--	self.inst.components.locomotor.walkspeed = 5.25+0.75
    end)

	

	
end




function PlayerController_3:UnMountBoat(forced)
	print("=====================U N MountBoat==================")

	if self.inst:HasTag("UnMountBoat") then return end
	self.inst:AddTag("UnMountBoat")
	self.inst:DoTaskInTime(1, function()	
    self.inst:RemoveTag("UnMountBoat")
	self.inst:RemoveTag("CheckingSailor")
    end)
	local wasboating = self.inst.boatingwith
	local toplayerboat = false
	local pt = FindLand(self.inst,2.5,0)
	if forced and forced == true and not pt then
		pt = FindLand(self.inst,2.5,-10)
		if not pt then pt = GetPlayer():GetPosition() end
	end

	if pt then
		print("land found")
	else
		toplayerboat = true
		pt = GetPlayer():GetPosition()
	end

	local dist = GetPlayer():GetDistanceSqToInst(self.inst)*0.1
	
	if dist>5 and toplayerboat == true and not forced then
		self.inst.components.talker:Say("I am at sea.")
		return
	end
	print("boat found getting  out")
	

	
	ChangeToCharacterPhysics(self.inst)
	self.inst.Physics:SetActive(true)
	
	self.inst:RemoveTag("CheckingSailor")
	
	if self.inst.boatingwith == 4 then
		self.inst.boatingwith = 0
		self.inst.components.driver:OnDismount(nil, pt)
	--	return
	end
	self.inst.components.moisture.baseDryingRate = 0
	self.inst.boatingwith = 0
	self.inst.sg:GoToState("player3jumpstart", pt)
	self.inst.components.playercontroller_3:Enable(false)
	
	self.inst:DoTaskInTime(18 / 30, function()	
		print("jump control end dismount")
		
		self.inst.startupdatingboatwithplayer = false
		self.inst.boatingwith = 0
		
		self.inst:RemoveTag("aquatic")

		--self.inst:AddComponent("Player3KeepOnLand")

		self.inst.components.playercontroller_3:Enable(true)

		self.inst.Transform:SetPosition(pt:Get())
		self.inst.components.activatable.inactive = nil
		--self.inst.components.locomotor.runspeed = 6.25 (player2,dist,step, angle, needsboat)
		self.inst:DoTaskInTime((self.plnum-2)*1.75, function()
			local pt3 = FindLand(self.inst,2.5,0)
		--	if 
			if (forced and forced == true and not pt3) then
				self:MountEmptyBoat(nil, 10)
			elseif toplayerboat==true and (wasboating==1 or wasboating==2 or wasboating==3) then
				self:MountBoat()
			end
		end)
	end)
	
	
	
	
end
--------========BOAT END========------------




--------========ABILITY=======-------------
function PlayerController_3:SpellCast()
---broken
---
end
--------========ABILITY END=======-------------

return PlayerController_3
