:NAME tripwire

:PARAM s_ping_effect@				trip_effect


:CONFIG float32 width

:GLOBAL c_node*		beam_node
:GLOBAL c_sound*	sound_activate


:VAR boolean tripped_last_tick

-- ------------------- constants ------------------- 

k_default_beam_width= 2
k_game_time_mode= e_value("e_time_mode", "_time_mode_game")

-- ------------------- initialization ------------------- 

-- remember 1 = open, 0 = closed

function param_initialize(p)
end

function config_initialize(c)
	c.width= 2
end

function var_initialize(v)
	v.tripped_last_tick= false
end

-- ------------------- component ------------------- 



function attach(object)
	local definition= object.definition
	local model= definition.model
	if (model) then
		local skeleton= model.skeleton
		if (skeleton) then
			local end_node= skeleton.node_get_by_name("end");
			local end_node_state= object.node_state_from_node(end_node)			
			end_node_state.position_set(config.width, 0)
			
			global.beam_node= skeleton.node_get_by_name("beam");
			local beam_node_state= object.node_state_from_node(global.beam_node)
			local width= config.width - (2 * beam_node_state.transform.offset.x)
			beam_node_state.scale_set(width/k_default_beam_width, 1)
		end
	end
	
	-- also set up our distance map
	local distance_map= object.distance_map_get()
	if (distance_map) then
		local world_position= object.world_position_get()
		local forward= object.forward_vector_get()
		local width= config.width
		
		local end_x= world_position.x + width*forward.x
		local end_y= world_position.y + width*forward.y

		distance_map.compute_on_line(world_position.x, world_position.y, end_x, end_y)
		
	end
	
	local sound= object.sound_get()
	if (sound) then
		global.sound_activate= sound.get_sound_by_name("activate")
	end
	
end

function update(object)	

	-- run the little system
	
	local ws= world_state_get()
	local iterator= ws.component_cache.component_player.iterator_get()
	local shortest_result= config.width
	local shortest_result_object= nil
	local world_position= object.world_position_get()
	local forward= object.forward_vector_get()
	local width= config.width
	
	while (true) do
		local player_component= iterator.next()
		if (player_component) then
			local player= player_component.object
			if (not player.is_hidden()) then
				local result= ws.raycast_object(player, world_position.x, world_position.y, forward.x, forward.y, width);
				
				if (result.intersected and result.distance < shortest_result) then
					shortest_result= result.distance
					shortest_result_object= player
				end			
			end
		else
			break
		end	
	end
	
	local tripped= false
	
	if (shortest_result_object) then
		local target_component= shortest_result_object.target_component_get()
		if (target_component) then
			local target= target_component.target_handle
			if (target and target.is_targetable()) then
				local end_x= world_position.x + width*forward.x
				local end_y= world_position.y + width*forward.y

				if (not var.tripped_last_tick) then
					local distance_map= object.distance_map_get()
					if (distance_map and param.trip_effect) then
						distance_map.distance_map.ping(param.trip_effect)
					end

					target.make_sound_on_line(world_position.x, world_position.y, end_x, end_y, 2, true)
					
					if (global.sound_activate) then
						global.sound_activate.play(k_game_time_mode)
					end				
				end

				target.make_sound_on_line(world_position.x, world_position.y, end_x, end_y, 0.05, false)			
				tripped= true
			end

		end
	end
	
	var.tripped_last_tick= tripped

	--scale them beam to the shortest result
	local beam_node_state= object.node_state_from_node(global.beam_node)
	local width= shortest_result - (2 * beam_node_state.transform.offset.x)
	beam_node_state.scale_set(width/k_default_beam_width, 1)
	
end

component_register(attach, update, nil, nil)
