---- Rulix aka Bak --- 21.7.2009

function printf(s, ...)
--	rx_ai.printf("bandage:"..s,...)
--	get_console():execute("flush")
end

local bg_ini = ini_file("misc\\rx_bandage.ltx")
local bandage_sets = {forbiddens = {items = {},factions = {},npcs = {}},
				check_prd = rx_utils.read_from_ini(bg_ini,"main","check_period",1500),
				enabled = rx_utils.read_from_ini(bg_ini,"main","enabled",true,0)}

function init()
	bandage_sets.max_h = rx_utils.read_from_ini(bg_ini,"main","medkit_health",50)/100
	bandage_sets.min_b = rx_utils.read_from_ini(bg_ini,"main","bandage_bleeding",0.2)
	bandage_sets.medkits = rx_utils.parse_list(bg_ini,"main","medkits")
	bandage_sets.bandages = rx_utils.parse_list(bg_ini,"main","bandages")
	bandage_sets.forbiddens.factions = rx_utils.parse_list(bg_ini,"main","forbidden_factions",true)
	bandage_sets.forbiddens.npcs = rx_utils.parse_list(bg_ini,"main","forbidden_npcs",true)
	bandage_sets.inited = true
end

local anims = {{a = "norm_torso_12_draw_0",t = 500},{a = "norm_torso_12_attack_0",t = 3600},{a = "norm_torso_12_holster_0",t = 300}} --,{a = "norm_torso_12_reload_0",t = 600}

class "evaluator_bandage" (property_evaluator)
function evaluator_bandage:__init(npc,name,storage) super (nil,name)
	self.st = storage
	rx_ai.subscribe_for_events(npc,self)
end
function evaluator_bandage:evaluate()
	local npc = self.object
	if self.hitt and self.hitt > time_global() then
--		printf("eva[%s]: false(hitt)",self.object:character_name())
		self.st.action = nil
		return false
	end
	local wpn = npc:active_item()
	if wpn and wpn:get_ammo_in_magazine() == 0 then
		self.st.action = nil
		return false
	end
	local medkit = self.st.medkit and npc:object(self.st.medkit)
	if not medkit then
		self.st.medkit = nil
		self.st.action = nil
	end
	if self.st.action and not rx_utils.npc_in_cover(npc) then
		self.st.action = nil
		self.hitt = time_global()+2000
		printf("eva[%s]: false(not cover)",self.object:character_name())
		return false
	end
	if medkit and self.st.action then
--		printf("eva[%s]: true(act)",self.object:character_name())
		return true
	end
	local wound,bleed = npc.health < bandage_sets.max_h,npc:get_bleeding() > bandage_sets.min_b
	if wound or bleed then
		if not medkit then
			local items = bandage_sets.bandages
			if wound then
				items = bandage_sets.medkits
			end
			for k,v in ipairs(items) do
				medkit = npc:object(v)
				if medkit then
					self.st.medkit = v
					printf("eva[%s]: find self.st.medkit %s",self.object:character_name(),self.st.medkit)
					break
				end
			end
		end
		if npc:best_enemy() and medkit and rx_utils.npc_in_cover(npc) then
--			printf("eva[%s]:self.st.medkit true",self.object:character_name())
			self.st.action = true
			printf("eva[%s]: true(check)",self.object:character_name())
			return true
		end
	else
--		self.st.action = nil
	end
	return false
end
function evaluator_bandage:hit_callback(amount)
	self.hitt = time_global()+4000
end


class "action_bandage" (action_base)
function action_bandage:__init (npc,action_name,storage) super (nil,action_name)
	self.st = storage
	rx_ai.subscribe_for_events(npc,self)
end
function action_bandage:initialize()
	action_base.initialize(self)
	local npc = self.object
	printf("act[%s]:init",self.object:character_name())
	if not npc:best_enemy() then
		self.st.action = nil
		return
	end
	npc:set_desired_position()
	npc:set_desired_direction()
	npc:set_movement_type(move.stand)
	npc:set_item(object.idle,nil)
	npc:clear_animations()
	self.dir = npc:direction()
	self.item = npc:object("rx_attach_bandage")
	self.timer = 0
	self.animst = 0
	state_mgr.set_state(npc,"idle")
	self.act = true
end
function action_bandage:execute()
	action_base.execute(self)
	local npc = self.object
--	printf("act[%s]:exec",self.object:character_name())
	npc:set_sight(look.direction,self.dir)
	if not self.item then
		self.item = npc:object("rx_attach_bandage")
	end
	if not self.st.action then
		printf("act[%s]:not self.st.action",self.object:character_name())
		npc:set_item(object.idle,rx_utils.get_weapon(npc))
		if self.item then
			self.item:enable_attachable_item(false)
		end
		return
	elseif npc:active_item() then
		printf("act[%s]:hide item",self.object:character_name())
		npc:set_item(object.idle,nil)
		return
	end
	local danger = npc:best_danger() or npc:best_enemy()
	if danger then
		npc:set_sight(look.point,danger:position())
	end
	if self.timer < time_global() then
		self.animst = self.animst+1
		printf("act[%s]:add anim %s(%s)",self.object:character_name(),self.animst,tostring(anims[self.animst] and anims[self.animst].a))
	else
		return
	end
	printf("act[%s]:exec2",self.object:character_name())
	if anims[self.animst] then
		printf("act[%s]:play anim",self.object:character_name())
		if self.item then
			self.item:enable_attachable_item(true)
		end
		npc:play_cycle(anims[self.animst].a,true)
		self.timer = time_global()+anims[self.animst].t
	else
		printf("act[%s]:end start",self.object:character_name())
		local medkit = self.st.medkit and npc:object(self.st.medkit)
		if medkit then
			printf("act[%s]:eat %s",self.object:character_name(),medkit:name())
			npc:eat(medkit)
		else
			printf("act[%s]:not medkit!",self.object:character_name())
			npc.health = 0.5
		end
		self.st.medkit = nil
		self.st.action = nil
		printf("act[%s]:end",self.object:character_name())
	end
	printf("act[%s]:exec3",self.object:character_name())
end
function action_bandage:finalize()
    action_base.finalize(self)
	local npc = self.object
	if self.st.medkit and self.animst and self.animst > 1 then
		printf("act[%s]: fin add hh",self.object:character_name())
		npc.health = 0.1
	end
--	if self.st.action then
		npc:set_item(object.idle,rx_utils.get_weapon(npc))
--	end
	printf("act[%s]:fin",npc:character_name())
	if npc:alive() then
		if self.item then
			printf("act[%s]:fin detach",npc:character_name())
			self.item:enable_attachable_item(false)
		end
	end
	self.st.action = nil
	self.act = nil
end
function action_bandage:hit_callback(amount)
	local npc = self.object
	if self.act and self.animst and self.animst > 1 and math.random() < 0.4 then
		local ban = npc:object("bandage")
		if ban then
			printf("hit_callback[%s]:drop %s",npc:character_name(),ban:name())
			npc:drop_item(ban)
			self.st.medkit = nil
		end
	end
end

evid_bandage = rx_ai.base_id+20
actid_bandage = evid_bandage

function add_to_binder(npc,ini,scheme,section,storage)
	if not bandage_sets.inited then
		init()
	end
	local manager = npc:motivation_action_manager()
	if not (bandage_sets.enabled and not bandage_sets.forbiddens.factions[npc:character_community()] and not bandage_sets.forbiddens.npcs[npc:name()]) then
		manager:add_evaluator(evid_bandage,property_evaluator_const(false))
		storage.disabled = true
		return
	else
		manager:add_evaluator(evid_bandage,evaluator_bandage(npc,"eva_bandage",storage))
	end
	local action = action_bandage(npc,"act_bandage",storage)
	action:add_precondition(world_property(stalker_ids.property_alive,true))
	action:add_precondition(world_property(xr_evaluators_id.sidor_wounded_base,false))
	if rx_gl then
		action:add_precondition(world_property(rx_gl.evid_gl_fire,false))
	end
	if rx_facer then
		action:add_precondition(world_property(rx_facer.evid_facer,false))
	end
	if xrs_grenade and xrs_grenade.evid_aaa_grenade then
--		action:add_precondition(world_property(xrs_grenade.evid_crazy_grenadier,false)) -- косячки
		action:add_precondition(world_property(xrs_grenade.evid_aaa_grenade,false))
	end
	if blowout_scheme and blowout_scheme.evid_outside then
		action:add_precondition(world_property(blowout_scheme.evid_outside,false))
	end
	action:add_precondition(world_property(evid_bandage,true))
	action:add_effect(world_property(evid_bandage,false))
	manager:add_action(actid_bandage,action)
	for i,id in ipairs({xr_actions_id.alife,stalker_ids.action_combat_planner,stalker_ids.action_danger_planner,xr_actions_id.stohe_meet_base+1,
	(xrs_medic and xrs_medic.actid_self_medic),(xrs_medic and xrs_medic.actid_medic),(watcher_act and watcher_act.actid_reach_item)}) do
		action = manager:action(id)
		action:add_precondition(world_property(evid_bandage,false))
	end
end

function npc_update(npc)
	local npc_id = npc:id()
	local st = db.storage[npc_id]["bandage"]
	if not bandage_sets.enabled or not st or st.disabled then
		return
	end
	local obj = npc:object("rx_attach_bandage")
	if not obj then
		alife():create("rx_attach_bandage",npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc_id)
	end
	if not (xrs_medic and db.storage[npc_id]["medic"]) then
		st = rx_ai.get_storage(npc_id,"rx_bandage")
		if time_global() > (st.spawn_time or 10000) then
			local ban
			for k,v in ipairs(bandage_sets.bandages) do
				ban = npc:object(v)
				if ban then
					break
				end
			end
			if not ban then
				if math.random() > 0.15 then
					printf("npc_update[%s]:spawn bandage",npc:character_name())
					alife():create(bandage_sets.bandages[math.random(#bandage_sets.bandages)],npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc_id)
				end
			end
			st.spawn_time = time_global()+math.random(100,400)*1000
		end
	end
end

local trem = {}

function npc_death(npc)
	local obj = npc:object("rx_attach_bandage")
	if obj then
		table.insert(trem,obj:id())
	end
end

function npc_switch_offline(npc)
	npc_death(npc)
end

function update()
	for i,id in ipairs(trem) do
		local sobj = alife():object(id)
		if sobj and sobj:section_name() == "rx_attach_bandage" then
			alife():release(sobj)
		end
	end
	trem = {}
end

function set_scheme(npc,ini,scheme,section)
	local st = xr_logic.assign_storage_and_bind(npc,ini,scheme,section)
end

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

