--[[
Developed by AMK-Team 
File:  amkIIxr_gatherer .script
Copyright:  ©  AMK-Team 2009
Author: Refresh

Since: 06.02.2009 0:55
	-- Заготовка для схемы.
Since: 07.02.2009 1:26
	-- Создан эвалуатор для поиска предметов и трупов (alfa) и экшен для посылки нпс к обьекту.
	-- Создан эвалуатор и экшен для контроля за позицией по отношению к целевому обьекту.
	-- Нпс определяют к какому предмету идти по его ценности.
Since: 07.02.2009 20:03
	-- Доработан шмон трупов.
	-- Экшены подьема айтима и шмона трупов обьединил в один.
	-- Создан эвалуатор и экшен для битья морды гг если он ворует айтимы.
Since: 09.02.2009 0:44
	-- Оптимизация кода, правка вылета (120: attempt to index local 'oFind' (a nil value))
	-- Поставлено условие денжера для схемы. Пусть не бьют актору морду под свистом пуль над головой.
	-- Внедрен модуль переодевания.
Since: 28.02.2009 14:51
	-- Пустые трупы больше не шмонаем.
	-- Эксклюзивные персы
--]]

local bEquip = false

iBase = 9030
iEvlSearch = iBase + 1
iEvlReachPosition = iBase + 2
iEvlPunch = iBase + 3

iActGoToPosition = iBase + 1
iActStealTrash = iBase + 2
iActPunch = iBase + 3

local aExclusive = {
	["yantar_ecolog_general"] = true, -- эколог
	["mil_freedom_member0021"] = true
}


local aItems={
    -- артефакты
	[clsid.artefact]		=500,
    [clsid.artefact_s]		=500,
	
	-- разная хрень...
    [clsid.device_detector_simple]=5,
    [clsid.device_pda]		=5,
    [clsid.device_torch_s]	=5,
	
	-- костюмы
    [clsid.equ_exo]			=200,
    [clsid.equ_military]	=150,
    [clsid.equ_scientific]	=100,
    [clsid.equ_stalker_s]	=80,
	
	-- медикаменты и хавчик
    [clsid.obj_antirad]		=8,
    [clsid.obj_attachable]	=8,
    [clsid.obj_bandage]		=3,
    [clsid.obj_bolt]		=3,
    [clsid.obj_bottle]		=8,
    [clsid.obj_food]		=8,
    [clsid.obj_medkit]		=10,
	
	-- стволы
	[clsid.wpn_fn2000]		=100,
	[clsid.wpn_rg6_s]		=100,
    [clsid.wpn_rpg7_s]		=100,
	[clsid.wpn_svd_s]		=80,
    [clsid.wpn_svu_s]		=80,
	[clsid.wpn_vintorez_s]	=80,
	[clsid.wpn_groza_s]		=60,
	[clsid.wpn_val_s]		=60,	
    [clsid.wpn_lr300_s]		=60,
    [clsid.wpn_ak74_s]		=50,
	[clsid.wpn_shotgun_s]	=50,
	[clsid.wpn_bm16_s]		=30,
    [clsid.wpn_hpsa_s]		=25,
    [clsid.wpn_usp45_s]		=25,	
	[clsid.wpn_fort]		=20,
    [clsid.wpn_walther_s]	=20,
    [clsid.wpn_pm_s]		=10,		
    [clsid.wpn_binocular_s]	=5,
    [clsid.wpn_knife_s]		=5,

	-- патроны и аддоны
	[clsid.wpn_silencer]	=5,
	[clsid.wpn_scope_s]		=5,
	[clsid.wpn_ammo]		=5,
    [clsid.wpn_ammo_m209]	=10,
    [clsid.wpn_ammo_og7b]	=10,
    [clsid.wpn_ammo_vog25]	=10,
    [clsid.wpn_wmagaz]		=5,
    [clsid.wpn_wmaggl]		=5
}

local aClmItems = {}
local aRobCorpses = {}


local aDanger = {
  [danger_object.hit] = true,
  [danger_object.attacked] = true,
  [danger_object.bullet_ricochet] = true,
  [danger_object.grenade] = true,
  [danger_object.entity_death] = true,
  [danger_object.enemy_sound] = true	
}

function amkRelsFind(st)
	if st.iFind then
		aClmItems[st.iFind] = nil
	end
	st.iFind = nil
end

function amkForgFind(st)
	st.iFind = nil
end

function amkOcupFind(st, oNpc)
	if st.iFind then
		local oFind = level.object_by_id(st.iFind) 
		if oFind and oFind:parent()==nil and not aClmItems[st.iFind] then
			st.iFind = oFind:id()
			aClmItems[st.iFind] = oNpc:id()
--			amkII._log("OcupFind: Npc => "..oNpc:name().." Find => "..oFind:name())
			return true
		end
	end
	return false
end

function amkCheckCorpse(oCorpse)
	if (IsStalker(oCorpse) or IsMonster(oCorpse)) and oCorpse:alive()==false then
		if aRobCorpses[oCorpse:id()]~=nil then
			return aRobCorpses[oCorpse:id()]
		end
		local cnt=0
		oCorpse:iterate_inventory(function (dummy, item)
        if item:section()~="bolt" then
          cnt=cnt+1
        end
			end, nil)
		aRobCorpses[oCorpse:id()]=cnt>0
		return aRobCorpses[oCorpse:id()]
	end
	return false
end

--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			       	     CAmkEvaluatorSearch 			                 *
-- *	Ищем всякое добро и трупы для шмона, контролируем валидность    *
-- * 	                             обьекта уже взятого на цель.                                            *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkEvaluatorSearch" (property_evaluator)
function CAmkEvaluatorSearch:__init(st) super (nil, "CAmkEvaluatorSearch")
	self.st = st
	self.iTimePeriod = time_global() + 2000
end

function CAmkEvaluatorSearch:evaluate()
	local oDanger = self.object:best_danger()	
	--[[
	--	Если на данный момент активен денжер из списка, и он активен уже не меннее 30сек... или нпс труп, или раненый, то ну его, этот шмон.
	--]]
	if (oDanger and aDanger[oDanger:type()] and time_global() - oDanger:time() < 30000) or
	self.object:alive() == false or xr_wounded.is_wounded(self.object) or self.object:best_enemy() then
		amkRelsFind(self.st)
		return false
	end
	
	--[[
	--	Если, мы свободны, гуляем и нам нечего украсть.
	--]]	
	if self.st.iFind == nil then		
		if self.iTimePeriod > time_global() then return false end
		self.iTimePeriod = time_global() + 25000		
		--[[
		--	Итерируем по увиденным, услышенным, обьектам в поисках добра.
		--]]	
		self.iMaxValue = 0
		self.st.bCorpse = false
		self.st.bItem = false		
		for object in self.object:memory_visible_objects() do
			self:CheckItem(object:object())
		end			
		for object in self.object:memory_sound_objects() do
			self:CheckItem(object:object())
		end
		return amkOcupFind(self.st, self.object) 	
	--[[
	--	Если у нас поставлена цель и мы жаждем её захватить себе.
	--]]	
	else
		--[[
		--	Проверяем наш обьект на валидность.
		-- 	Существует ли он, не украл ли его кто-то, не слишком ли он далеко, можно ли до него дойти.
		--]]	
		local oFind = level.object_by_id(self.st.iFind)
		if oFind ~= nil then
			if oFind:parent() == nil then
				if self.object:position():distance_to(oFind:position()) < 35 and self.object:accessible(oFind:level_vertex_id()) then
					return true 
				end
			elseif oFind:parent():id() == db.actor:id() then
--				amkII._log("CAmkEvaluatorSearch : ActorMudak <= "..self.object:name())
				self.object:clear_animations()
				self.st.bPunch = true
			end
		end
		--[[
		--	Отпускаем обьект.
		--]]			
		amkRelsFind(self.st)
		return false
	end
	return false	
end

--[[
--	CheckItem(oFind)
--	Ищем цель для захвата.
--	@param	object	oFind		Обьект.
--]]
function CAmkEvaluatorSearch:CheckItem(oFind)
	local iFndId = oFind:id()
	--[[
	--	Если обьект захвачен, то проверяем нпс на валидность.
	--]]		
	if aClmItems[iFndId] then
		local iNpcId = aClmItems[iFndId]
		local oNpc = level.object_by_id(iNpcId)
		if oNpc == nil or oNpc:alive() == false or oNpc:id() == self.object:id() or xr_wounded.is_heavy_wounded_by_id(iNpcId) then
			aClmItems[oFind:id()] = nil
		else
			return
		end
	end
	--[[
	--	Проверяем обьект.
	--]]
	if aClmItems[iFndId] then return end
	if self.object:position():distance_to(oFind:position()) >= 35 then return end
	if self.object:accessible(oFind:level_vertex_id()) == false then return end
	if oFind:parent() ~= nil then return end
	if self.st.aInaccesObj and self.st.aInaccesObj[iFndId] == true then return end
	--[[
	--	Если у нас трупик...
	--]]	
	if amkCheckCorpse(oFind) == true then	
		local iValue = 50 / self.object:position():distance_to(oFind:position())
		if iValue > self.iMaxValue then
			self.st.bCorpse = true
			self.st.bItem   = false		
			self.st.iFind   = oFind:id()
			self.iMaxValue  = iValue
		end
	--[[
	--	Если у нас айтим...
	--]]		
	elseif aItems[ get_clsid(oFind) ] ~= nil then
		local iValue = aItems[get_clsid(oFind)] / self.object:position():distance_to(oFind:position())
		if iValue > self.iMaxValue then
			self.st.bCorpse = false
			self.st.bItem   = true		
			self.st.iFind   = oFind:id()
			self.iMaxValue  = iValue
		end
	end
end


--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			       	     CAmkActionGoToPosition 			                 *
-- *             Посылаем нпс к его находке, и контролируем его путь.                *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkActionGoToPosition" (action_base)
function CAmkActionGoToPosition:__init(st) super (nil, "CAmkActionGoToPosition")
	self.st = st
end

function CAmkActionGoToPosition:initialize()
	action_base.initialize(self)
	--[[
	--	инициализируем переменные.
	--]]	
	self.oFind 		 = level.object_by_id(self.st.iFind) 
	self.iCurLvidNpc = self.object:level_vertex_id()
	self.iCurLvidObj = self.oFind:level_vertex_id()
	self.iTime 		 = time_global()	
	--[[
	--	Задаем параметры движения нпс.
	--]]	
	self.object:set_detail_path_type(move.curve)
	self.object:set_path_type(game_object.level_path)		
	self.object:set_sight(look.danger,nil,0)
	self.object:movement_enabled(true)	
	--[[
	--	Если у нас активен денжер, то подкрадываемся, иначе идем свободно.
	--]]		
	if self.object:best_danger() and time_global() - self.object:best_danger():time() < 30000 then
		state_mgr.set_state(self.object, "sneak",nil,nil,nil,{animation = true})	
	else
		state_mgr.set_state(self.object, "walk",nil,nil,nil,{animation = true})
	end
	--[[
	--	Посылаем нпс в вертекс находки.
	--]]		
	self.object:set_dest_level_vertex_id(self.iCurLvidObj)
end

function CAmkActionGoToPosition:execute()
	action_base.execute(self)
	--[[
	--	Контроллируем позицию нпс, чтоб не застрял на месте.
	--]]
	if self.iCurLvidNpc == self.object:level_vertex_id() then
		if time_global() - self.iTime > 10000 then
			if self.st.aInaccesObj == nil then self.st.aInaccesObj = {} end
			self.st.aInaccesObj[self.oFind:id()] = true
			amkRelsFind(self.st)
		end
	else
		self.iCurLvidNpc = self.object:level_vertex_id()
		self.iTime = time_global()
	end	
	--[[
	--	Если нашу находку кто-то сдвинул с места, то перенапрявляем нпс.
	--]]	
	if self.iCurLvidObj ~= self.oFind:level_vertex_id() then
		self.iCurLvidObj = self.oFind:level_vertex_id()
		self.object:set_dest_level_vertex_id(self.iCurLvidObj)
	end
end



--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			         CAmkEvaluatorReachPosition 			                 *
-- *         		Проверяем, не пришел ли нпс к обьекту.                              *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkEvaluatorReachPosition" (property_evaluator)
function CAmkEvaluatorReachPosition:__init(st) super (nil, "CAmkEvaluatorReachPosition")
	self.st = st
end

function CAmkEvaluatorReachPosition:evaluate()
	if self.st.iFind == nil then return false end
	local oFind = level.object_by_id(self.st.iFind)	
	--[[
	--	Проверяем, не пришел ли нпс на место назначения.
	--]]	
	if oFind then
		if self.object:position():distance_to(oFind:position()) < 1.2 then
			return true
		else
			return false
		end
	end
	--[[
	--	Похоже не пришел.
	--]]	
	return false
end


--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			              CAmkActionStealTrash 			                 *
-- *			Проигрываем анимации и забираем добро.		      *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkActionStealTrash" (action_base)
function CAmkActionStealTrash:__init(st) super (nil, "CAmkActionStealTrash")
	self.st = st
end

function CAmkActionStealTrash:initialize()
	action_base.initialize(self)
	--[[
	--	Если наш обьект айтим. Анимация - dinamit_1, время - 1000мс
	--]]	
	if self.st.bItem == true then 
		local oFind = level.object_by_id(self.st.iFind)
		self.iTime = time_global() + 1000
		self.object:add_animation("dinamit_1")
	--[[
	--	Если наш обьект трупик. Состояние - search, время - 6000мс
	--]]		
	elseif self.st.bCorpse == true then 
		local oCorpse = level.object_by_id(self.st.iFind)
		self.iTime = time_global() + 6000
		state_mgr.set_state(self.object, "search", nil, nil, {look_object = oCorpse})
	end	
end

function CAmkActionStealTrash:execute()
	action_base.execute(self)
	--[[
	--	Если наш обьект айтим.
	--]]	
	if self.st.bItem == true then 
		local oFind = level.object_by_id(self.st.iFind)
		if self.iTime > time_global() then
			return
		end		
		--[[
		--	Если предмет никто не хапнул, то спокойно делаем трансфер.
		--]]		
		if oFind ~= nil and oFind:parent() == nil then
			oFind:transfer_item(oFind, self.object)
			self.object:enable_memory_object(oFind, false)	
	
		end
		self.object:clear_animations()
		amkRelsFind(self.st)
	--[[
	--	Если наш обьект трупик.
	--]]		
	elseif self.st.bCorpse == true then 
		local oCorpse = level.object_by_id(self.st.iFind)
		if self.iTime > time_global() then
			return
		end	
		--[[
		--	Естли трупик цел, то обчищаем его инвентарь.
		--]]			
		if oCorpse ~= nil and oCorpse:parent() == nil then
			oCorpse:iterate_inventory(function (d, oItem)
				if oItem and oItem:parent() and oItem:parent():id()==oCorpse:id() then
					if oItem:section()~="bolt" then 
						oCorpse:transfer_item(oItem, self.object)
						--[[
						--	+ Module "AmkDisguise"
						--]]
						--if bEquip then
							--if (amkII_equip) and (amkII_equip.aOutfitsList[oItem:section()]) then
								--amkII_equip.CAmkDisguise():Update(self.object, oItem)
							--end
						--end
					end
				end
			end, nil)		
			aRobCorpses[oCorpse:id()] = false
		end
		self.object:clear_animations()
		amkRelsFind(self.st)
	end
end	


--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			              CAmkEvaluatorPunch 			                            *
-- *	        Проверяем, не получен ли флаг на удар по морде гг.                    *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkEvaluatorPunch" (property_evaluator)
function CAmkEvaluatorPunch:__init(st) super (nil, "CAmkEvaluatorPunch")
	self.st = st
end

function CAmkEvaluatorPunch:evaluate()
	if self.st.bPunch == true then
		if self.object:position():distance_to(db.actor:position()) <= 8 then
			local oDanger = self.object:best_danger()	
			if oDanger and aDanger[oDanger:type()] and time_global() - oDanger:time() < 30000 then
				self.st.bPunch = false
				return false
			end	
			return true
		else
			self.st.bPunch = false
		end
	end
	return false
end


--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			              CAmkEvaluatorPunch 			                            *
-- *        Подбегаем и бьем морду гг, если тыкает стволом, то отбираем.      *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

class "CAmkActionPunch" (action_base)
function CAmkActionPunch:__init(st) super (nil, "CAmkActionPunch")
	self.st = st
end

function CAmkActionPunch:initialize()
	action_base.initialize(self)
	self.object:set_desired_position()
	self.object:set_desired_direction()	
	--[[
	--	Задаем тип перемещения.
	--]]				
	self.object:set_detail_path_type(move.curve)
	self.object:set_path_type(game_object.level_path)		
	self.object:set_sight(look.danger,nil,0)
	self.object:movement_enabled(true)
	--[[
	--	Задаем состояние движения и материм актора.
	--]]		
	state_mgr.set_state(self.object, "sprint",nil,nil,{look_object = db.actor}, {animation = true})
	self.object:set_dest_level_vertex_id(db.actor:level_vertex_id())
	xr_sound.set_sound_play(self.object, "use_abuse")
end

function CAmkActionPunch:execute()
	action_base.execute(self)
	--[[
	--	Если мы уже на месте, ставим флажок.
	--]]	
	if self.bReach ~= true then	
		if self.object:position():distance_to(db.actor:position()) < 2.0 then
			self.iStep  = 1
			self.bReach = true	
		else
			if self.object:accessible(db.actor:level_vertex_id()) then
				self.object:set_dest_level_vertex_id(db.actor:level_vertex_id())
			else
				xr_sound.set_sound_play(self.object, "use_abuse")
				self.st.bPunch = false
			end	
			return
		end
	end	
	--[[
	--	Первый шаг. - Проигрываем анимацию удара.
	--]]	
	if self.iStep == 1 then
		state_mgr.set_state(self.object, "punch", nil, nil, {look_object = db.actor}, {animation = true})								
		self.iStep = 2
		self.iTime = time_global() + 500
	--[[
	--	Второй шаг. - Через пол сек, если гг не успел убежать, то задаем камере еффектор и наносим актору хит.
	--]]		
	elseif self.iStep == 2 and self.iTime < time_global() then
		if self.object:position():distance_to(db.actor:position()) < 3.0 then		
			--[[
			--	Эффектор головокружения.
			--]]			
			level.add_cam_effector("camera_effects\\fusker.anm", 999, false, "")
			local oSnd = sound_object("actor\\pain_3")
			oSnd:play_at_pos(self.object, self.object:position())
			--[[
			--	Забираем активное оружие.
			--]]			
			if db.actor:active_item() then
				local sSec = db.actor:active_item():section()
				if sSec ~= "bolt" and sSec ~= "wpn_knife" and sSec ~= "wpn_binoc" then
					db.actor:transfer_item(db.actor:active_item(), self.object)
				end
			end
			--[[
			--	Наносим хит.
			--]]				
			local h = hit()
			h.draftsman = db.actor
			h.type = hit.strike
			h.direction = self.object:position():sub(self.object:position())
			h:bone("pelvis")
			h.power = 0.5
			h.impulse = 5
			db.actor:hit(h)
		end
		self.iStep = 3
		self.iTime = time_global() + 1000
	--[[
	--	Третий шаг. - Через сек, выключаем схему.
	--]]	
	elseif self.iStep == 3 and self.iTime < time_global() then	
		self.st.bPunch = false
	end
end

function CAmkActionPunch:finalize()
	self.bReach = false
	self.iStep = 0
	action_base.finalize(self)
end




--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- *			             	LogicBinder 			                            *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

--[[
--	add_to_binder(object, char_ini, scheme, section, st)
--	Добавление схемы в планировщик.
--]]
function add_to_binder(object, char_ini, scheme, section, st)
	local oNpc = object
	local oManager = oNpc:motivation_action_manager()
	local property_wounded = xr_evaluators_id.sidor_wounded_base
	
	if (oNpc:story_id()~=4294967296 or aExclusive[oNpc:name()]==true or oNpc:character_community()=="zombied" or 
	oNpc:character_community()=="trader") then
		oManager:add_evaluator(iEvlSearch, property_evaluator_const(false))
		oManager:add_evaluator(iEvlReachPosition, property_evaluator_const(false))
		oManager:add_evaluator(iEvlPunch, property_evaluator_const(false))
	else	
		oManager:add_evaluator(iEvlSearch, CAmkEvaluatorSearch(st))
		oManager:add_evaluator(iEvlReachPosition, CAmkEvaluatorReachPosition(st))
		oManager:add_evaluator(iEvlPunch, CAmkEvaluatorPunch(st))
		
		-- ' Подбежать к найденному добру.
		local oNewAction = CAmkActionGoToPosition(st)
		oNewAction:add_precondition(world_property(stalker_ids.property_alive, true))
		oNewAction:add_precondition(world_property(stalker_ids.property_enemy, false))
		oNewAction:add_precondition(world_property(xr_evaluators_id.stohe_meet_base + 1, false))
		oNewAction:add_precondition(world_property(property_wounded, false))
		oNewAction:add_precondition(world_property(iEvlSearch, true))
		oNewAction:add_precondition(world_property(iEvlReachPosition, false))
		oNewAction:add_precondition(world_property(iEvlPunch, false))
		oNewAction:add_effect(world_property(iEvlReachPosition, true))
		oManager:add_action(iActGoToPosition, oNewAction)
		
		-- ' Забрать найденное добро.
		oNewAction = CAmkActionStealTrash(st)
		oNewAction:add_precondition(world_property(stalker_ids.property_alive,true))
		oNewAction:add_precondition(world_property(stalker_ids.property_enemy,false))
		oNewAction:add_precondition(world_property(property_wounded,false))
		oNewAction:add_precondition(world_property(iEvlSearch,true))
		oNewAction:add_precondition(world_property(iEvlReachPosition,true))
		oNewAction:add_precondition(world_property(iEvlPunch, false))	
		oNewAction:add_effect(world_property(iEvlReachPosition, false))
		oNewAction:add_effect(world_property(iEvlSearch, false))
		oManager:add_action(iActStealTrash, oNewAction)
		
		-- ' Вмазать гг по морде, если он украл добро.	
		oNewAction = CAmkActionPunch(st)
		oNewAction:add_precondition(world_property(stalker_ids.property_alive,true))
		oNewAction:add_precondition(world_property(stalker_ids.property_enemy,false))
		oNewAction:add_precondition(world_property(property_wounded,false))	
		oNewAction:add_precondition(world_property(iEvlPunch, true))	
		oNewAction:add_effect(world_property(iEvlPunch, false))
		oManager:add_action(iActPunch, oNewAction)
			
		-- ' Ограничение на alife.	
		oNewAction = oManager:action(xr_actions_id.alife)
		oNewAction:add_precondition(world_property(iEvlSearch, false))
		oNewAction:add_precondition(world_property(iActPunch, false))
		
		-- ' Ограничение на danger.	
		oNewAction = oManager:action(stalker_ids.action_danger_planner)
		oNewAction:add_precondition(world_property(iEvlSearch, false))
		oNewAction:add_precondition(world_property(iActPunch, false))
	end
end


function set_scheme(object, ini, scheme, section)
	local st = xr_logic.assign_storage_and_bind(object, ini, scheme, section)
	st.enabled = true
end

function disable_scheme(npc, scheme)
	local st = db.storage[npc:id()][scheme]
	if st then
		st.enabled = false
	end
end
