with (collision_circle(x, y, 50, obj_enemy, false, true)) instance_destroy()

image_speed = 0
sprite_index = spr_player

hsp = 0
vsp = 0
walksp = 7
accl = 0.4

hp = 3
mercy_timer = 150
mercy_timer_max = mercy_timer
is_mercy = false

spr_walk = spr_player
spr_idle = spr_player

//image index, but for our direction
local_frame = 0

hit = -1

///@func move_and_collide()
///@returns N/A
move_and_collide = function(){
	// horizontal collision
	if (place_meeting(x + hsp, y, obj_wall)){
		while (!place_meeting(x + sign(hsp), y, obj_wall)){
			x = x + sign(hsp)
		}
		hsp = 0
	}
	x = x + hsp

	// vertical collision
	if (place_meeting(x, y + vsp, obj_wall)){
		while (!place_meeting(x, y + sign(vsp), obj_wall)){
			y = y + sign(vsp)
		}
		vsp = 0
	}
	y = y + vsp
}

///@func animate()
///@returns N/A
animate = function() {
	var _total_frames = sprite_get_number(sprite_index) / 4
	image_index = local_frame + (CARDINAL_DIR * _total_frames)

	local_frame += sprite_get_speed(sprite_index) / 60

	//if animation would loop
	if (local_frame >= _total_frames){
		anim_end_local = true
		local_frame -= _total_frames
	}
	else anim_end_local = false
}

state = new StateMachine("idle")

state.add("idle", {
	enter: function() {
		sprite_index = spr_idle
	},
	step: function() {
		if (input_magnitude != 0) state_switch("walk")
		
		if (controls.attack_right || controls.attack_left || controls.attack_up || controls.attack_down) state_switch("attack")
	}
})
state.add("walk", {
	step: function() {
		hsp += lengthdir_x(input_magnitude * accl, input_direction)
		vsp += lengthdir_y(input_magnitude * accl, input_direction)
		
		if (!controls.left && !controls.right) hsp = 0
		if (!controls.up && !controls.down) vsp = 0
		
		hsp = clamp(hsp, -walksp, walksp)
		vsp = clamp(vsp, -walksp, walksp)
			
		move_and_collide()
		
		var _old_sprite = sprite_index
			
		if (input_magnitude != 0){
			direction = input_direction
			sprite_index = spr_walk
		}
		else{
			hsp = lengthdir_x(lerp(hsp, 0, accl), input_direction)
			vsp = lengthdir_y(lerp(vsp, 0, accl), input_direction)
			
			if (hsp == 0 && vsp == 0) state_switch("idle")
		}
			
		if (_old_sprite != sprite_index) local_frame = 0
		animate()
		
		if (controls.attack_right || controls.attack_left || controls.attack_up || controls.attack_down) state_switch("attack")
	}
})

state.add("attack", {
	enter: function(){
		if (controls.attack_right) direction = 0
		else if (controls.attack_left) direction = 180
		else if (controls.attack_up) direction = 90
		else if (controls.attack_down) direction = 270
		
		sprite_index = spr_player_attack
		local_frame = 0
		image_index = 0
		
		if (!ds_exists(hit, ds_type_list)) hit = ds_list_create()
		ds_list_clear(hit)
		
		hsp *= 0.3
		vsp *= 0.3
	},
	step: function(){
		#region calculate attack
		mask_index = spr_player_attack_mask
		
		var _hit_this_frame = ds_list_create()
		var _hits = instance_place_list(x, y, all, _hit_this_frame, false)
		
		if (_hits > 0){
			for (var _i = 0; _i < _hits; _i++){
				var _inst = _hit_this_frame[| _i]
				if (ds_list_find_index(hit, _inst) == -1){
					ds_list_add(hit, _inst)
					
					with (_inst){
						if (object_index == obj_enemy){
							audio_play_sound(sfx_hit, 2, false)
							state_switch("hurt")
						}
						else if (object_index == obj_enemy_fast){
							audio_play_sound(sfx_hit, 2, false)
							switch (other.direction){
								case 0: hsp = 8; break
								case 90: vsp = -8; break
								case 180: hsp = -8; break
								case 270: vsp = 8; break
							}
							state_switch("hurt")
						}
						else if (object_index == obj_enemy_green){
							audio_play_sound(sfx_hit, 2, false)
							switch (other.direction){
								case 0: hsp = 4; break
								case 90: vsp = -4; break
								case 180: hsp = -4; break
								case 270: vsp = 4; break
							}
							state_switch("hurt")
						}
						else if (object_index == obj_bullet){
							audio_play_sound(sfx_hit, 2, false)
							repeat (10) instance_create_layer(x, y, "Instances", obj_dust)
							instance_destroy()
						}
						else if (object_index == obj_boulder || object_index == obj_crate){
							image_index++
							audio_play_sound(sfx_wood, 2, false)
						}
						else if (object_index == obj_chair){
							repeat (20) instance_create_layer(x, y, "Instances", obj_splinter)
							audio_play_sound(sfx_wood, 2, false)
							instance_destroy()
						}
					}
				}
			}
		}
		
		ds_list_destroy(_hit_this_frame)
		mask_index = spr_player
		#endregion
		
		move_and_collide()
		
		animate()
		if (anim_end_local){
			anim_end_local = false
			state_switch(get_previous_state(id))
		}
	},
})
