function nway( x, y, v, ang, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot01( x, y, v, ang, kind, late ) ;
    ang += dang ;
    }
}

function nwaylaser( x, y, v, ang, length, width, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateLaser01( x, y, v, ang, length, width, kind, late ) ;
    ang += dang ;
    }
}

function nwaylaserB( x, y, v, ang, ang2, omega, leng, dleng, wid, way, dang, kind, late, kf )
// ang2…設置点の移動速度
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateLaserA( 0, x, y, leng, wid, kind, late ) ;
    SetLaserDataA( 0, 0, ang, omega, dleng, v, ang2 ) ;
    SetShotKillTime( 0, kf ) ;
    FireShot( 0 ) ;
    ang += dang ;
    }
}

function NwayHavingSpace( x, y, space, v, ang, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot01( x + space * cos( ang ), y + space * sin( ang ), v, ang, kind, late ) ;
    ang += dang ;
    }
}

function NwayLaserHavingSpace( x, y, space, v, ang, length, width, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateLaser01( x + space * cos( ang ), y + space * sin( ang ), v, ang, length, width, kind, late ) ;
    ang += dang ;
    }
}

function NwayLaserHavingSpaceEx( x, y, space, v, ang, stang, length, width, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateLaser01( x + space * cos( ang ), y + space * sin( ang ), v, ang + stang, length, width, kind, late ) ;
    ang += dang ;
    }
}

function NwayHavingSpaceEx( x, y, space, v, ang, stang, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot01( x + space * cos( ang ), y + space * sin( ang ), v, ang + stang, kind, late ) ;
    ang += dang ;
    }
}

function NwayHavingSpaceEx2( x, y, space, v, a, maxv, ang, stang, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot02( x + space * cos( ang ), y + space * sin( ang ), v, ang + stang, a, maxv, kind, late ) ;
    ang += dang ;
    }
}

function NwayHavingSpaceEx3( x, y, space, v, ang, shtang, way, dang, kind, late )
// 全ての弾が一つの方向に飛ぶ
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot01( x + space * cos( ang ), y + space * sin( ang ), v, shtang, kind, late ) ;
    ang += dang ;
    }
}

function nwayhard( x, y, v, a, maxv, ang, way, dang, kind, late )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateShot02( x, y, v, ang, a, maxv, kind, late ) ;
    ang += dang ;
    }
}

function nwayluna( x, y, v, xa, ya, maxxv, maxyv, ang, way, dang, kind, late )
{
let xv ;
let yv ;
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    xv = v * cos( ang ) ;
    yv = v * sin( ang ) ;
    CreateShot12( x, y, xv, yv, xa, ya, maxxv, maxyv, kind, late ) ;
    ang += dang ;
    }
}

function NwayOval( x, y, xv, yv, ang, oang, a, maxv, way, dang, kind, late )
// oang…楕円の角度
{
let nxv ;
let nyv ;
let v ;
let shotang ;
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    nxv = xv * cos( ang ) ;
    nyv = yv * sin( ang ) ;
    v = ( ( ( nxv ) ^ 2 ) + ( ( nyv ) ^ 2 ) ) ^ 0.5 ;
    shotang = atan2( nyv, nxv ) + oang ;
    CreateShot02( x, y, v, shotang, a, maxv, kind, late ) ;
    ang += dang ;
    }
}

function nwayextra( x, y, v, adeg, a, maxv, ang, way, dang, kind, late )
{
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
loop( way )
  {
  CreateShotA( 0, x, y, late ) ;
  SetShotDataA( 0, 0, v, ang, adeg, a, maxv, kind ) ;
  FireShot( 0 ) ;
  ang += dang ;
  }
}

function moveToPlayer( xMove, yAdd, frame, left, top, right, bottom )
{
//   xMove  : x 方向の移動量（正の数）
//   yAdd   : y 方向の移動量
//   frame  : 移動に要するフレーム数
//   left   : 以下、可動範囲
//   top    :
//   right  :
//   bottom :
    let x;
    let y;

    if(GetPlayerX < GetX) {
        // プレイヤーより右に敵がいれば、敵は左に動きます。
        x = GetX - xMove;

        // 但し、敵が可動領域の左端よりも左にいくようなら、右に動きます。
        if(x < left) {
            x = GetX + xMove;
        }
    } else {
        // さもなくば、敵は右に動きます。
        x = GetX + xMove;

        // 但し、敵が可動領域の右端よりも右にいくようなら、左に動きます。
        if(right < x) {
            x = GetX - xMove;
        }
    }

    // 可動領域の外に行く場合は、端っこで止めます。
    y = GetY + yAdd;
    if(y < top) {
        y = top;
    } else if(bottom < y) {
        y = bottom;
    }

    SetMovePosition02(x, y, frame);
}


 // ---------------------------------------
  // CreateReflectShot02関数
  // 　壁で反射する弾を生成する関数です。
  // 　引数：11個
  // 
  // PosX       : 発射点のX座標
  // PosY       : 発射点のY座標
  // Speed      : 弾の初速
  // Angle      : 弾の角度
  // Accelerate : 弾の1フレームごとの加速量
  // MaxSpeed   : 最大速度
  // Graphic    : 弾の画像
  // Delay      : 弾が発射されるまでの遅延時間
  // Wall       : 上下左右それぞれの壁で反射するかどうか
  // Count      : 反射回数（0を指定すると無制限）
  // Frame      : 弾の生存フレーム数（0を指定すると無制限）
  // 
  // 返り値     : オブジェクト型（内部的にはreal値、生成した弾オブジェクトを指す）
  // 
  // Wallに設定する引数について
  // 　Wallには2進数で4桁のフラグを指定してください。
  // 　0（＝0000）を指定した場合、壁での反射を行いません。
  // 　15（＝1111）を指定した場合、すべての壁で反射します。
  // 　個別に反射する壁を指定したい場合は、足し算を行ってください。
  // 　それぞれの壁を示す数字は、上：8　左：4　右：2　下：1　です。
  // 　たとえば、上と左と右の壁で反射する弾を生成したい場合、
  // 　Wallには引数として「8＋4＋2＝14」を与えてください。
  // 
  // -改定履歴----------------------------------------------------------------------------------------
  // 2007/12/27 新規作成
  // 2007/12/30 生存フレーム数の設定を追加、Wall設定用のグローバル変数を追加
  // 2008/06/25 構成をちょっと変更、Wikiに投稿
  // -------------------------------------------------------------------------------------------------
  
  // Wall設定用のグローバル変数
  let WALL_TOP = 8;
  let WALL_LEFT = 4;
  let WALL_RIGHT = 2;
  let WALL_BOTTOM = 1;
  
  // 関数本体
  function CreateReflectShot02(PosX,PosY,Speed,Angle,Accelerate,MaxSpeed,Graphic,Delay,Wall,Count,Frame) {
  	let Obj = Obj_Create(OBJ_SHOT);
  	
  	// オブジェクト弾の基本パラメータを設定します。
  	Obj_SetPosition(Obj,PosX,PosY);
  	Obj_SetSpeed(Obj,Speed);
  	Obj_SetAngle(Obj,Angle);
  	ObjShot_SetGraphic(Obj,Graphic);
  	ObjShot_SetDelay(Obj,Delay);
  	
  	// 描画領域を超えても自動削除は行わないように設定します。
  	Obj_SetAutoDelete(Obj,false);
  	
  	// タスクを呼び出して反射制御を行います。
  	CreateReflectShot02Task(Obj,Accelerate,MaxSpeed,Wall,Count,Frame);
  	
  	// 生成したオブジェクトを示す値を返り値に返します。
  	return Obj;
  }
  
  // 反射制御を行うサブタスク
  task CreateReflectShot02Task(Obj,Accelerate,MaxSpeed,Wall,argCount,argFrame) {
  	let Count = argCount;
  	let CountFlag = (Count > 0);
  	let Frame = argFrame;
  	let FrameFlag = (Frame > 0);
  	let Top = (floor(Wall / 8) == 1);
  	let Left = (floor((Wall % 8) / 4) == 1);
  	let Right = (floor((Wall % 4) / 2) == 1);
  	let Bottom = (Wall % 2 == 1);
  	let X = Obj_GetX(Obj);
  	let Y = Obj_GetY(Obj);
  	let Speed = Obj_GetSpeed(Obj);
  	let Angle = Obj_GetAngle(Obj);
  	
  	// 弾が画面外に生成されていた場合、
  	// 　弾の速度と角度から、弾が画面内に入れるかどうかを計算します。
  	
  	// X軸方向、Y軸方向それぞれに1フレームごとに進む量を計算します。
  	let OneStepX = cos(Angle) * Speed;
  	let OneStepY = sin(Angle) * Speed;
  	
  	// X軸方向で弾が画面内に入るフレーム、画面外に出るフレームを計算します。
  	let InFrameX = (GetClipMinX - X) / OneStepX;
  	let OutFrameX = (GetClipMaxX - X) / OneStepX;
  	if (InFrameX > OutFrameX) {
  		let Work = InFrameX;
  		InFrameX = OutFrameX;
  		OutFrameX = Work;
  	}
  	
  	// Y軸方向で弾が画面内に入るフレーム、画面外に出るフレームを計算します。
  	let InFrameY = (GetClipMinY - Y) / OneStepY;
  	let OutFrameY = (GetClipMaxY - Y) / OneStepY;
  	if (InFrameY > OutFrameY) {
  		let Work = InFrameY;
  		InFrameY = OutFrameY;
  		OutFrameY = Work;
  	}
  	
  	// X軸方向に入る前にY軸方向から抜けてしまう場合、
  	// またはY軸方向に入る前にX軸方向から抜けてしまう場合、
  	// 弾は画面内に入る弾道ではないため、弾オブジェクトを削除します。
  	if ((InFrameX > OutFrameY)||(InFrameY > OutFrameX)) {
  		Obj_Delete(Obj);
  	}
  	
  	// 弾が削除されるか、画面内に入るまで待ちます。
  	while (Obj_BeDeleted(Obj) == false) {
  		X = Obj_GetX(Obj);
  		Y = Obj_GetY(Obj);
  		Speed = Obj_GetSpeed(Obj);
  		
  		// 弾が画面内に入った場合、ループを抜けます。
  		if ((X >= GetClipMinX)&&(X <= GetClipMaxX)&&(Y >= GetClipMinY)&&(Y <= GetClipMaxY)) {
  			break;
  		}
  		
  		// 弾の加速処理を行います。
  		if (Accelerate > 0) {
  			if (Speed + Accelerate < MaxSpeed) {
  				Obj_SetSpeed(Obj,Speed + Accelerate);
  			}
  		} else if (Accelerate < 0) {
  			if (Speed + Accelerate > MaxSpeed) {
  				Obj_SetSpeed(Obj,Speed + Accelerate);
  			}
  		}
  		
  		yield;
  		
  		// 生存フレーム判定フラグがオンになっている場合、
  		// 　弾の生存フレーム数を更新します。
  		// 　生存フレーム数が尽きた場合、オブジェクトを削除します。
  		if (FrameFlag == true) {
  			Frame -= 1;
  			if (Frame <= 0) {
  				Obj_Delete(Obj);
  			}
  		}
  	}
  	
  	// 弾が削除されるまで、反射判定と反射処理を繰り返します。
  	while (Obj_BeDeleted(Obj) == false) {
  		X = Obj_GetX(Obj);
  		Y = Obj_GetY(Obj);
  		Speed = Obj_GetSpeed(Obj);
  		Angle = Obj_GetAngle(Obj);
  		
  		// 反射したかどうかを判定します。
  		// 　①座標が描画範囲を超えていること（＝弾が壁を越えたこと）
  		// 　②座標が越えた壁が、反射対象になっていること
  		// 　③反射回数が残っていること、または反射回数判定フラグがオフになっていること
  		// この３つの条件をすべて満たした場合のみ、反射処理を行います。
  		if (Y < GetClipMinY) {
  			if ((Top == true)&&((Count > 0)||(CountFlag == false))) {
  				Y = (GetClipMinY * 2) - Y;
  				Angle = 0 - Angle;
  				Count -= 1;
  			} else {
  				Obj_Delete(Obj);
  			}
  		}
  		if (Y > GetClipMaxY) {
  			if ((Bottom == true)&&((Count > 0)||(CountFlag == false))) {
  				Y = (GetClipMaxY * 2) - Y;
  				Angle = 0 - Angle;
  				Count -= 1;
  			} else {
  				Obj_Delete(Obj);
  			}
  		}
  		if (X < GetClipMinX) {
  			if ((Left == true)&&((Count > 0)||(CountFlag == false))) {
  				X = (GetClipMinX * 2) - X;
  				Angle = 180 - Angle;
  				Count -= 1;
  			} else {
  				Obj_Delete(Obj);
  			}
  		}
  		if (X > GetClipMaxX) {
  			if ((Right == true)&&((Count > 0)||(CountFlag == false))) {
  				X = (GetClipMaxX * 2) - X;
  				Angle = 180 - Angle;
  				Count -= 1;
  			} else {
  				Obj_Delete(Obj);
  			}
  		}
  		
  		// 弾の加速処理を行います。
  		if (Accelerate > 0) {
  			if (Speed + Accelerate < MaxSpeed) {
  				Obj_SetSpeed(Obj,Speed + Accelerate);
  			}
  		} else if (Accelerate < 0) {
  			if (Speed + Accelerate > MaxSpeed) {
  				Obj_SetSpeed(Obj,Speed + Accelerate);
  			}
  		}
  		
  		Obj_SetPosition(Obj,X,Y);
  		Obj_SetAngle(Obj,Angle);
  		
  		yield;
  		
  		// 生存フレーム判定フラグがオンになっている場合、
  		// 　弾の生存フレーム数を更新します。
  		// 　生存フレーム数が尽きた場合、オブジェクトを削除します。
  		if (FrameFlag == true) {
  			Frame -= 1;
  			if (Frame <= 0) {
  				Obj_Delete(Obj);
  			}
  		}
  	}
  }


function wait( n )
{
loop( n ) { yield ; }
}

function GapOfEtoP
{
	return ( atan2( GetPlayerY - GetY, GetPlayerX - GetX ) ) ;
}

function GapOfOtoP( obj )
{
return ( atan2( GetPlayerY - Obj_GetY( obj ), GetPlayerX - Obj_GetX( obj ) ) ) ;
}

function GapOfOtoO( objA, objB )
{
return ( atan2( Obj_GetY( objB ) - Obj_GetY( objA ), Obj_GetX( objB ) - Obj_GetX( objA ) ) ) ;
}

function GapOfXYtoP( x, y )
{
return ( atan2( GetPlayerY - y, GetPlayerX - x ) ) ;
}

function GapOfOtoE( obj )
{
return ( atan2( GetY - Obj_GetY( obj ), GetX - Obj_GetX( obj ) ) ) ;
}

function CreateReflectNway( x, y, v, ang, a, maxv, way, dang, kind, late, wall, count, frame )
{
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    CreateReflectShot02( x, y, v, ang, a, maxv, kind, late, wall, count, frame ) ;
    ang += dang ;
    }
}

function Obj_SetSpeedAndAngle( obj, v, ang )
{
Obj_SetSpeed( obj, v ) ;
Obj_SetAngle( obj, ang ) ;
}

function GetLengthEtoP
{
return ( GetGapLength( GetX, GetY, GetPlayerX, GetPlayerY ) ) ;
}

function GetLengthOtoP( obj )
{
return ( GetGapLength( Obj_GetX( obj ), Obj_GetY( obj ), GetPlayerX, GetPlayerY ) ) ;
}

function CicringShot( x, y, bv, av, ang, degv, a, maxv, kind, late, frame )
{
CreateShotA( 0, x, y, late ) ;
SetShotDataA( 0, 0, bv, ang, degv, a, maxv, kind ) ;
SetShotDataA( 0, frame, av, NULL, 0, a, maxv, kind ) ;
FireShot( 0 ) ;
}

function VShot( x, y, v, a, ang, maxv, size, shapeang, bulletsp, kind, late )
// size…大きさ。弾数はsize*2+1になる。意味ないけど0も指定可能。
// shapeang…Ｖの角度。ここの数字は実際の角度の半分。
// bulletsp…隣り合う弾のスペース。
{
let space ;
CreateShot02( x, y, v, ang, a, maxv, kind, late ) ;
space = bulletsp ;
loop( size )
  {
  CreateShot02( x + space * cos( 180 - shapeang + ang ), y + space * sin( shapeang - ang ), v, ang, a, maxv, kind, late ) ;
  space += bulletsp ;
  }
space = bulletsp ;
loop( size )
  {
  CreateShot02( x + ( space * cos( 180 + shapeang + ang ) ), y + ( space * sin( - shapeang - ang ) ), v, ang, a, maxv, kind, late ) ;
  space += bulletsp ;
  }
}

function VShotB( x, y, v, ang, a, maxv, size, dang, dv, kind, late )
// v…先頭部分なのであまり遅くしすぎないように
// size…大きさ。弾数はsize*2+1になる。意味ないけど0も指定可能。
// dang…Ｖの形成関係の部分。
// dv…Ｖの形成関係の部分。
{
let fv = v ;
let fang = ang ;
CreateShot02( x, y, v, ang, a, maxv, kind, late ) ;
loop( size )
  {
  v -= dv ;
  ang += dang ;
  CreateShot02( x, y, v, ang, a, maxv, kind, late ) ;
  }
v = fv ;
ang = fang ;
loop( size )
  {
  v -= dv ;
  ang -= dang ;
  CreateShot02( x, y, v, ang, a, maxv, kind, late ) ;
  }
}

function nwayspecial( id, x, y, v, ang, way, dang, kind, late )
// AddShotに使うことに向いているかも
// 普通に使うならFireShot( idからid+way )は必須
{
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
loop( way )
  {
  CreateShotA( id, x, y, late ) ;
  SetShotDataA( id, 0, v, ang, 0, 0, NULL, kind ) ;
  id += 1 ;
  ang += dang ;
  }
}

function nwayspecialB( id, x, y, v, ang, omega, a, maxv, way, dang, kind, late )
// AddShotに使うことに向いているかも
// 普通に使うならFireShot( idからid+way )は必須
{
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
loop( way )
  {
  CreateShotA( id, x, y, late ) ;
  SetShotDataA( id, 0, v, ang, omega, a, maxv, kind ) ;
  id += 1 ;
  ang += dang ;
  }
}

function nwayspecialex( id, x, y, xspace, yspace, v, a, maxv, adeg, ang, stang, way, dang, kind, late )
// AddShotに使うことに向いているかも
// 普通に使うならFireShot( idからid+way )は必須
{
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
loop( way )
  {
  CreateShotA( id, x + xspace * cos( ang ), y + yspace * sin( ang ), late ) ;
  SetShotDataA( id, 0, v, ang + stang, adeg, a, maxv, kind ) ;
  id += 1 ;
  ang += dang ;
  }
}

function nwayspecialex2( id, x, y, xspace, yspace, v, a, maxv, adeg, ang, way, dang, kind, late )
// AddShotに使うことに向いているかも
// 普通に使うならFireShot( idからid+way )は必須
// 同じ方向へ発射する版
{
let ang2 = ang;
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
loop( way )
  {
  CreateShotA( id, x + xspace * cos( ang ), y + yspace * sin( ang ), late ) ;
  SetShotDataA( id, 0, v, ang2, adeg, a, maxv, kind ) ;
  id += 1 ;
  ang += dang ;
  }
}

function NwaySpecialOval( id, x, y, xv, yv, ang, oang, omega, a, maxv, way, dang, kind, late )
// oang…楕円の角度
{
let nxv ;
let nyv ;
let v ;
let shotang ;
  ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
  loop( way )
    {
    nxv = xv * cos( ang ) ;
    nyv = yv * sin( ang ) ;
    v = ( ( ( nxv ) ^ 2 ) + ( ( nyv ) ^ 2 ) ) ^ 0.5 ;
    shotang = atan2( nyv, nxv ) + oang ;
    CreateShotA( id, x, y, late ) ;
    SetShotDataA( id, 0, v, shotang, omega, a, maxv, kind ) ;
    ang += dang ;
    id += 1 ;
    }
}

function Obj_AccelY( obj, ay )
{
let vx ;
let vy ;
let av ;
let aang ;
let bv = Obj_GetSpeed( obj ) ;
let bang = Obj_GetAngle( obj ) ;
vx = bv * cos( bang ) ;
vy = bv * sin( bang ) + ay ;
av = ( vx ^ 2 + vy ^ 2 ) ^ 0.5 ;
aang = atan2( vy, vx ) ;
Obj_SetSpeedAndAngle( obj, av, aang ) ;
}

function Obj_AccelX( obj, ax )
{
let vx ;
let vy ;
let av ;
let aang ;
let bv = Obj_GetSpeed( obj ) ;
let bang = Obj_GetAngle( obj ) ;
vx = bv * cos( bang ) + ax ;
vy = bv * sin( bang ) ;
av = ( vx ^ 2 + vy ^ 2 ) ^ 0.5 ;
aang = atan2( vy, vx ) ;
Obj_SetSpeedAndAngle( obj, av, aang ) ;
}

function Obj_Accel( obj, a, ang )
{
let v = Obj_GetSpeed( obj ) ;
let vx ;
let vy ;
let av ;
let aang ;
let bang = Obj_GetAngle( obj ) ;
vx = v * cos( bang ) + a * cos( ang ) ;
vy = v * sin( bang ) + a * sin( ang ) ;
av = ( vx ^ 2 + vy ^ 2 ) ^ 0.5 ;
aang = atan2( vy, vx ) ;
Obj_SetSpeedAndAngle( obj, av, aang ) ;
}

task gballex( shot, obj, x, y, v, ang, kind, late )
// shot…重力をかける方
// obj…重力がかかる方
{
Obj_SetCollisionToObject( shot, true ) ;
Obj_SetPosition( shot, x, y ) ;
Obj_SetSpeedAndAngle( shot, v, ang ) ;
ObjShot_SetGraphic( shot, kind ) ;
ObjShot_SetDelay( shot, late ) ;
while ( Obj_BeDeleted( shot ) == false )
  {
  Obj_Accel( shot, ( 1.5 / 60 ), GapOfOtoO( shot, obj ) ) ;
  yield ;
  }
}

task gball( shot, x, y, v, a, ang, kind, late )
{
Obj_SetCollisionToObject( shot, true ) ;
Obj_SetPosition( shot, x, y ) ;
Obj_SetSpeedAndAngle( shot, v, ang ) ;
ObjShot_SetGraphic( shot, kind ) ;
ObjShot_SetDelay( shot, late ) ;
while ( Obj_BeDeleted( shot ) == false )
  {
  Obj_Accel( shot, a, GapOfOtoE( shot ) ) ;
  yield ;
  }
}

function randallang
{
return( rand( -180, 180 ) ) ;
}

function ObjEffect_SetVertexXYSquare( obj, x1, y1, x2, y2 )
{
ObjEffect_SetVertexXY( obj, 0, x1, y1 ) ;
ObjEffect_SetVertexXY( obj, 1, x1, y2 ) ;
ObjEffect_SetVertexXY( obj, 2, x2, y1 ) ;
ObjEffect_SetVertexXY( obj, 3, x2, y2 ) ;
}

function ObjEffect_SetVertexUVSquare( obj, x1, y1, x2, y2 )
{
ObjEffect_SetVertexUV( obj, 0, x1, y1 ) ;
ObjEffect_SetVertexUV( obj, 1, x1, y2 ) ;
ObjEffect_SetVertexUV( obj, 2, x2, y1 ) ;
ObjEffect_SetVertexUV( obj, 3, x2, y2 ) ;
}

function nwayCardioid( x, y, minv, maxv, ang, way, dang, kind, late )
{
let fang = ang ;
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
let dv = ( maxv - minv ) / 2 ;
loop( way )
  {
  CreateShot01( x, y, minv + dv * ( cos( fang - ang ) + 1 ), ang, kind, late ) ;
  ang += dang ;
  }
}

function nwayCardioidEx( x, y, minv, topv, ang, a, maxv, way, dang, kind, late )
{
let fang = ang ;
ang = ang - ( ( ( way - 1 ) / 2 ) * dang ) ;
let dv = ( topv - minv ) / 2 ;
loop( way )
  {
  CreateShot02( x, y, minv + dv * ( cos( fang - ang ) + 1 ), ang, a, maxv, kind, late ) ;
  ang += dang ;
  }
}

task Circle( gra1 )
{
let cir = Obj_Create( OBJ_EFFECT ) ;
ObjEffect_SetTexture( cir, gra1 ) ;
ObjEffect_SetRenderState( cir, ALPHA ) ;
ObjEffect_SetPrimitiveType( cir, PRIMITIVE_TRIANGLESTRIP ) ;
ObjEffect_SetLayer( cir, 1 ) ;
ObjEffect_CreateVertex( cir, 4 ) ;
ObjEffect_SetVertexXYSquare( cir, -174, -178, 174, 178 ) ;
ObjEffect_SetVertexUVSquare( cir, 0, 0, 348, 356 ) ;
ObjEffect_SetScale( cir, 0.4, 0.4 ) ;
let ang = 0 ;
loop
  {
  Obj_SetPosition( cir, GetX, GetY ) ;
  ObjEffect_SetAngle( cir, 0, 0, ang ) ;
  ang += 1.2 ;
  yield ;
  }
}

task CircleEx( gra1, x, y, scale, omega )
{
let cir = Obj_Create( OBJ_EFFECT ) ;
ObjEffect_SetTexture( cir, gra1 ) ;
ObjEffect_SetRenderState( cir, ALPHA ) ;
ObjEffect_SetPrimitiveType( cir, PRIMITIVE_TRIANGLESTRIP ) ;
ObjEffect_SetLayer( cir, 1 ) ;
ObjEffect_CreateVertex( cir, 4 ) ;
ObjEffect_SetVertexXYSquare( cir, -( x / 2 ), -( y / 2 ), x / 2, y / 2 ) ;
ObjEffect_SetVertexUVSquare( cir, 0, 0, x, y ) ;
ObjEffect_SetScale( cir, scale, scale ) ;
let ang = 0 ;
loop
  {
  Obj_SetPosition( cir, GetX, GetY ) ;
  ObjEffect_SetAngle( cir, 0, 0, ang ) ;
  ang += omega ;
  yield ;
  }
}

task backfire( obj, kind, late, gap )
{
while ( Obj_BeDeleted( obj ) == false )
  {
  CreateShotA( 0, Obj_GetX( obj ), Obj_GetY( obj ), late ) ;
  SetShotDataA( 0, 0, 0, 0, 0, 0, NULL, kind ) ;
  SetShotKillTime( 0, 0 ) ;
  FireShot( 0 ) ;
  wait( gap ) ;
  }
}

task satellite( obj, r, startang, dang, kind, late )
{
let st = Obj_Create( OBJ_SHOT ) ;
let ang = startang ;
Obj_SetPosition( st, Obj_GetX( obj ) + r * cos( ang ), Obj_GetY( obj ) + r * sin( ang ) ) ;
Obj_SetSpeedAndAngle( st, 0, ang ) ;
ObjShot_SetGraphic( st, kind ) ;
ObjShot_SetDelay( st, late ) ;
while ( Obj_BeDeleted( obj ) == false )
  {
  Obj_SetPosition( st, Obj_GetX( obj ) + r * cos( ang ), Obj_GetY( obj ) + r * sin( ang ) ) ;
  ang += dang ;
  yield ;
  }
Obj_Delete( st ) ;
}

task satelliteB( obj, r, xspan, yspan, startang, dang, kind, late )
{
let st = Obj_Create( OBJ_SHOT ) ;
let ang = startang ;
Obj_SetPosition( st, ( Obj_GetX( obj ) + r * cos( ang ) ) * xspan, ( Obj_GetY( obj ) + r * sin( ang ) ) * yspan ) ;
Obj_SetSpeedAndAngle( st, 0, ang ) ;
ObjShot_SetGraphic( st, kind ) ;
ObjShot_SetDelay( st, late ) ;
while ( Obj_BeDeleted( obj ) == false )
  {
  Obj_SetPosition( st, ( Obj_GetX( obj ) + r * cos( ang ) ) * xspan, ( Obj_GetY( obj ) + r * sin( ang ) ) * yspan ) ;
  ang += dang ;
  yield ;
  }
Obj_Delete( st ) ;
}

function ObjShot_SetAllData( shot, x, y, v, ang, kind, late )
{
Obj_SetPosition( shot, x, y ) ;
Obj_SetSpeed( shot, v ) ;
Obj_SetAngle( shot, ang ) ;
ObjShot_SetGraphic( shot, kind ) ;
ObjShot_SetDelay( shot, late ) ;
}

function ObjLaser_SetAllData( las, x, y, ang, len, wid, kind, late )
{
Obj_SetPosition( las, x, y ) ;
Obj_SetAngle( las, ang ) ;
ObjShot_SetGraphic( las, kind ) ;
ObjShot_SetDelay( las, late ) ;
ObjLaser_SetWidth( las, wid ) ;
ObjLaser_SetLength( las, len ) ;
}