function enemy_move_and_collide()
{
	x_spd_kb = lerp(x_spd_kb, 0, 0.2);
	if abs(x_spd_kb) < 1
		x_spd_kb = 0;

	y_spd_kb = lerp(y_spd_kb, 0, 0.2);
	if abs(y_spd_kb) < 1
		y_spd_kb = 0;
		
	var _y_spd_total = (y_spd + y_spd_kb) * global.time_scale;
	var _x_spd_total = (x_spd + x_spd_kb) * global.time_scale;
	
    if place_meeting(x, y + _y_spd_total, oParentSolid) && apply_collision
    {
        while !place_meeting(x, y + sign(_y_spd_total), oParentSolid)
            y += sign(_y_spd_total);
			
        _y_spd_total = 0;
		y_spd = 0;
		y_spd_kb = 0;
    }
    y += _y_spd_total;

    if place_meeting(x + _x_spd_total, y, oParentSolid) && apply_collision
    {
        while !place_meeting(x + sign(_x_spd_total), y, oParentSolid)
            x += sign(_x_spd_total);
			
        _x_spd_total = 0;
		x_spd = 0;
		x_spd_kb = 0;
    }
    x += _x_spd_total;
}

function enemy_check_hazard()
{
    var _hazard = instance_place(x, y, oParentHazard);
    if _hazard == noone exit;
    
    hp -= _hazard.damage;
    if hp <= 0
    {
        is_dead = true;
        enemy_death();
    }
}

function enemy_check_hitstun()
{
	if hitstun_timer > 0
	{
		hitstun_timer -= global.time_scale;
	
		x_spd = 0;
		y_spd = 0;
		
		if global.developer_mode
			image_blend = c_orange;
	}
	else
	{
		image_index += animation_spd;
		
		enemy_ai();
		
		image_blend = c_white;
	}
}

function enemy_death()
{
	//death_pe(); 没有_info传参，不要去注释！！
	if !is_undefined(death_callback)
		death_callback();
	else
	{
		var _corpse = icd(oEnemyCorpse, x, y, 50);
		_corpse.sprite_index = corpse_sprite;
		if corpse_doll
		{
			_corpse.x_spd = x_spd_kb;
			_corpse.y_spd = -max(abs(y_spd_kb), abs(x_spd_kb));
			_corpse.apply_gravity = true;
		}
		instance_destroy();
	}	
}

/// @desc 优雅地以该实例为原点，给定宽高、偏移与持续时间为参数，生成敌人middle/left碰撞箱（多用于横向攻击）
/// @param {real} _x 碰撞箱宽度
/// @param {real} _y 碰撞箱高度
/// @param {real} _x_offset 碰撞箱与该实例在x轴上的偏移量，默认为0
/// @param {real} _y_offset 碰撞箱与该实例在y轴上的偏移量，默认为0
/// @param {real} _duration 碰撞箱持续时间，默认为0，即无限
function enemy_create_hitboxML(_x, _y,
_x_offset = 0, _y_offset = 0, _duration = 0)
{
	var _hb = icd(oEnemyHitbox, x + _x_offset, y + _y_offset);
	_hb.owner = id;
	_hb.sprite_index = sEnemyHitboxML;
	_hb.x_offset = _x_offset;
	_hb.y_offset = _y_offset;
	
	var _base = 2;
	_hb.image_xscale = _x / _base * facing_x;
	_hb.image_yscale = _y / _base;
/*
oEnemyHitbox的基础大小为2*2
因为gml的1*1sprite无法将重心放在middle/center
此处定义后续用于缩放
*/	
	if _duration != 0
	{
		_hb.hitbox_type = "BLADE";
		_hb.duration = _duration;
	}
	return _hb;
}

/// @desc 优雅地以该实例为原点，给定宽高为参数，生成敌人middle/center碰撞箱（多用于空中本体，射弹等）
/// @param {real} _x 碰撞箱宽度
/// @param {real} _y 碰撞箱高度
function enemy_create_hitboxMC(_x, _y)
{
	var _hb = icd(oEnemyHitbox, x, y);
	_hb.owner = id;
	_hb.sprite_index = sEnemyHitboxMC;
	
	var _base = 2;
	_hb.image_xscale = _x / _base;
	_hb.image_yscale = _y / _base;

	return _hb;
}
/// @desc 优雅地以该实例为原点，给定宽高、偏移与持续时间为参数，生成敌人bottom/center碰撞箱（多用于地面本体、纵向攻击等）
/// @param {real} _x 碰撞箱宽度
/// @param {real} _y 碰撞箱高度
/// @param {real} _x_offset 碰撞箱与该实例在x轴上的偏移量，默认为0
/// @param {real} _y_offset 碰撞箱与该实例在y轴上的偏移量，默认为0
/// @param {real} _duration 碰撞箱持续时间，默认为0，即无限
function enemy_create_hitboxBC(_x, _y,
_x_offset = 0, _y_offset = 0, _duration = 0)
{
	var _hb = icd(oEnemyHitbox, x + _x_offset, y + _y_offset);
	_hb.owner = id;
	_hb.sprite_index = sEnemyHitboxBC;
	_hb.x_offset = _x_offset;
	_hb.y_offset = _y_offset;
	
	var _base = 2;
	_hb.image_xscale = _x / _base;
	_hb.image_yscale = _y / _base;

	if _duration != 0
	{
		_hb.hitbox_type = "BLADE";
		_hb.duration = _duration;
	}
	return _hb;
}

function weighted_pick(_weights)
{
    var _total = 0;
    for (var i = 0; i < array_length(_weights); i++)
        _total += _weights[i];
    
    var _roll = irandom(_total - 1);
    var _acc  = 0;
    for (var i = 0; i < array_length(_weights); i++)
    {
        _acc += _weights[i];
        if _roll < _acc
            return i;
    }
}