#TouhouDanmakufu[Player]
#ScriptVersion[3]
#ID["gt_CirnoA01"]
#Title["Cirno A"]
#Text["Perfect Freeze Cirno"]
#Image["./CirnoCutin.png"]
#ReplayName["gt_CirnA"]

/* 
Version 1.5
By: gtbot

Common Data system has been replaced with object oriented data values.
As such, Common Data support for ice barrier is removed.

The only common data function this player uses is an area one:
	Area "CirnoPlayer"
	Value "SystemType"
		Expected: "Cirno_System" or any other arbitrary string
		What it does:	Anything other than "Cirno_System" will 
						increase ice gain overall

Create an obj value with Obj_SetValue.
	Using "MediumBullet" as the name will spawn large ice
	Using "SmallBullet" as the name will spawn medium ice
	Using "Fireball" will flag the bullet as unfreezable except in bombs
	Setting a bullet to have spell resistance will make it totally unfreezable

	If you'd like, you can initialize the value "IceBreak" to 0, 
		but do not change it beyond that. You can also completely
		skip this since it's done on its own
		
	Using the data values override the default shotsystem freezing
		for only that bullet in particular

*/

let AllowFreeze = true; // Setting to false stops freezing

let MaximumParticles = 128; 

let CheckBulletMax = 8; // This number limits how each block of ice will freeze for each bullet per frame
// Lower numbers means less lag when there's more bullets, but also less reliablility
// This number is disregarded for the initial Ice Barrier ice


let GetCirnoState = STATE_NORMAL;

let unshiftspd = 5;
let shiftspd = 2;
let playerdead = false;
let IsPlayerSpawning = false;

let FreezeCharge = 0;
let FreezeMeter = 100;
let FreezeTime = FreezeMeter*1.4;
let FreezeScene = 0;
let FreezeInc = 0.04;

let FreezeBeginCharge = 28;
let FreezeEndCharge = 58;

let LastFreezeX = 0;
let LastFreezeY = 0;
let LastFreezeID = ID_INVALID;
let TotalParticleCount = 0;

let ShotDamage = 0;
let ShotCount = 2;
let LifeCount = 99;
let BombCount = 99;
let CanShoot = true;
let IceBullets = [];

let objPlayer = GetPlayerObjectID;
let objPlayer1 = ObjPrim_Create(OBJ_SPRITE_2D);
let objPlayer2 = ObjPrim_Create(OBJ_SPRITE_2D);
let current = GetCurrentScriptDirectory;

let imgPlayer = current ~ "Cirno.png";
let imgPlayer2 = current ~ "Cirno2.png";
let imgField = current ~ "icefield.png";
let imgEffect = current ~ "ice.png";
let imgBullet = current ~ "CirnoBullet.png";
let imgCharged = current ~ "charged.png";
let imgAscii = current ~ "CirnoAscii.png";

let spellsnd = ObjSound_Create;
let chargesnd = ObjSound_Create;

@Initialize{
	LoadPlayerShotData(current ~ "CirnoA_shotdata.txt"); 
	CreateCommonDataArea("CirnoPlayer");

	ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 2, 20); 
	
	SetPlayerSpeed(unshiftspd,shiftspd);
	SetPlayerClip(11,11,GetStgFrameWidth-11,GetStgFrameHeight-18);
	SetPlayerAutoItemCollectLine(128);

	LoadSound(current~"se_pldead.wav");
	LoadSound(current~"se_shot.wav");
	LoadSound(current~"se_spell.wav");
	LoadSound(current~"se_getlife.wav");
	LoadSound(current~"se_getbomb.wav");
	LoadSound(current~"se_graze.wav");
	LoadSound(current~"se_item.wav");
	LoadSound(current~"se_powerup.wav");
	LoadSound(current~"se_charge.wav");
	LoadSound(current~"se_charged.wav");	
	LoadSound(current~"se_ice.wav");
	LoadSound(current~"se_ice2.wav");
	LoadSound(current~"se_pin00.wav");
	LoadSound(current~"se_pin01.wav");
	ObjSound_Load(spellsnd, current~"se_spark.wav");
	ObjSound_Load(chargesnd, current~"se_charge.wav");
	
	LoadTexture(imgPlayer);
	LoadTexture(imgPlayer2);
	LoadTexture(imgField);
	LoadTexture(imgEffect);
	LoadTexture(imgBullet);
	LoadTexture(imgCharged);
	
	RenderPlayerImage(objPlayer, 1);
	RenderPlayerImage(objPlayer, 2);
	
	RenderChargeReady(1);
	
	DrawFreezeMeterList;	
	
	SetAreaCommonData("CirnoPlayer", "IceArea", 300);
	SetAreaCommonData("CirnoPlayer", "PerfectFreeze", 100);
	SetPlayerPower(4.75);
	SetPlayerSpell(2);
	
	CheckForAreaCommonData;
	CirnoShotType;
	Spawn;
}


@MainLoop{
	if(GetCirnoState==STATE_DOWN){CanShoot = false; FreezeCharge = 0;}
	if(GetCirnoState==STATE_NORMAL){CanShoot = true;}
	if(IsPermitPlayerShot==false && GetCirnoState==STATE_NORMAL){CanShoot = false;}
	if(IsPermitPlayerShot==true && GetCirnoState==STATE_NORMAL){CanShoot = true;}
	
	if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH){RenderHitboxImage(objPlayer, 0, 1);}
	
	if(!IsPlayerSpawning){
		SetPlayerClip(11,11,GetStgFrameWidth-11,GetStgFrameHeight-18);
	}
	
	if(!IsPlayerSpellActive){
		if(FreezeCharge>FreezeBeginCharge){
			SetPlayerSpeed(shiftspd,shiftspd);
		}else{
			SetPlayerSpeed(unshiftspd,shiftspd);
		}
	}
	if(GetCirnoState!=STATE_DOWN){
		if(LifeCount<truncate(GetPlayerLife)&&GetPlayerLife>0){PlaySE(current~"se_getlife.wav");LifeCount=GetPlayerLife;}else{LifeCount=GetPlayerLife;}
		if(BombCount<truncate(GetPlayerSpell)){PlaySE(current~"se_getbomb.wav");BombCount=GetPlayerSpell;}else{BombCount=GetPlayerSpell;}
	}
	
	if(FreezeScene != 1 && CanShoot == true){
		AddToCharge(0.04);
	}
	if(FreezeScene != 0){
		FreezeCharge = 0;
	}
	
	
	if(floor(FreezeMeter) == 30 && FreezeCharge<FreezeBeginCharge){PlaySE(current~"se_pin00.wav");AddToCharge(1);}
	if(floor(FreezeMeter) == 99){PlaySE(current~"se_pin01.wav");AddToCharge(1);}
	
	SetAreaCommonData("CirnoPlayer", "IcePower", FreezeMeter);
	SetAreaCommonData("CirnoPlayer", "IceArea", GetPlayerPower*100);
	SetAreaCommonData("CirnoPlayer", "PerfectFreeze", GetPlayerSpell*100);
	
	if(GetAreaCommonData("CirnoPlayer", "IncreaseIce", 0)>0){
		AddToCharge(GetAreaCommonData("CirnoPlayer", "IncreaseIce", 0)/75);
		SetPlayerLife(GetPlayerLife+GetAreaCommonData("CirnoPlayer", "IncreaseIce", 0)/1626);
		SetAreaCommonData("CirnoPlayer", "IncreaseIce", 0);
	}
	yield;
}

@Finalize{
	RemoveSound(current~"se_pldead.wav");
	RemoveSound(current~"se_shot.wav");
	RemoveSound(current~"se_spell.wav");
	RemoveSound(current~"se_life.wav");
	RemoveSound(current~"se_graze.wav");
	RemoveSound(current~"se_item.wav");
	RemoveSound(current~"se_charge.wav");
	RemoveSound(current~"se_charged.wav");	
	RemoveSound(current~"se_ice.wav");
	RemoveSound(current~"se_ice2.wav");
	RemoveSound(current~"se_pin00.wav");
	RemoveSound(current~"se_pin01.wav");
	RemoveSound(current~"se_spark.wav");
	RemoveSound(current~"se_charge.wav");
	
	RemoveTexture(imgPlayer);
	RemoveTexture(imgPlayer2);
	RemoveTexture(imgField);
	RemoveTexture(imgEffect);
	RemoveTexture(imgBullet);
	RemoveTexture(imgCharged);
}

@Event{
	alternative(GetEventType)
	case(EV_REQUEST_SPELL){
		let spell = GetPlayerSpell;
		if(spell >= 1 && FreezeScene != 2 && GetCirnoState != STATE_DOWN && GetCirnoState != STATE_END){
			SetScriptResult(true);
			PlaySE(current~"se_spell.wav");
			SetPlayerSpell(spell-1);
			PerfectFreeze;
		}else{
			SetScriptResult(false);
		}
	}
	case(EV_PLAYER_SHOOTDOWN){
		CanShoot = false;
		playerdead = true;
		GetCirnoState = STATE_END;
	}
	case(EV_HIT){
		PlaySE(current~"se_pldead.wav");
		ClearEnemyBullets(GetPlayerX, GetPlayerY, 10, 8, 900, GetPlayerRebirthFrame+31);
		loop(9){IceParticle(GetPlayerX, GetPlayerY, rand(0,360), 1);}
		loop(24){MapleLeaf(GetPlayerX, GetPlayerY, rand(0,360), rand(85, 185), 2.8);}
		CancelCollectItems;
		DeathExplosion;
		FalseDeath(GetCirnoState);
		SetPlayerSpeed(0, 0);
		GetCirnoState = STATE_HIT;
	}
	case(EV_PLAYER_REBIRTH){
		SetPlayerSpell(GetPlayerSpell+0.25);
		ClearEnemyBullets(GetPlayerX, GetPlayerY, 10, 15, 200, 0);
		SetPlayerInvincibilityFrame(180);
		playerdead = false;
		AddToCharge(100);
		Spawn;
		GetCirnoState = STATE_NORMAL;
	}
	case(EV_GET_ITEM){
		if(GetAreaCommonData("CirnoPlayer", "SystemType", "Default_System")=="Cirno_System"){
			if(GetEventArgument(0)==17){
				PlaySE(current~"se_item.wav");
				SetPlayerLife(GetPlayerLife+0.01);
				return;
			}
		}
		alternative(GetEventArgument(0))
		case(ITEM_SPELL){
			PlaySE(current~"se_getbomb.wav");
			SetPlayerSpell(GetPlayerSpell+1);
		}
		case(ITEM_SPELL_S){
			PlaySE(current~"se_getbomb.wav");
			SetPlayerSpell(GetPlayerSpell+1);
		}
		case(ITEM_1UP){
			PlaySE(current~"se_getlife.wav");
			SetPlayerLife(GetPlayerLife+1);
		}
		case(ITEM_1UP){
			PlaySE(current~"se_getlife.wav");
			SetPlayerLife(GetPlayerLife+1);
		}
		others{
			PlaySE(current~"se_item.wav");
		}
	}
	case(EV_GRAZE){
		PlaySE(current~"se_graze.wav");
		AddToCharge(1);
	}
}

task FalseDeath(realdeath){
	if(realdeath==STATE_NORMAL){return;}
	ObjPlayer_ClearIntersection(objPlayer);
	loop(GetPlayerRebirthFrame+1){SetPlayerSpeed(0, 0);yield;}
	if(IsPlayerSpellActive){
		GetCirnoState = STATE_NORMAL;
		ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 2, 20); 
		return;
	}
	GetCirnoState = STATE_DOWN;
	playerdead = true;
	SetPlayerLife(GetPlayerLife-1);
	loop(GetPlayerDownStateFrame+1){SetPlayerSpeed(0, 0);yield;}
	NotifyEvent(GetOwnScriptID, EV_PLAYER_REBIRTH, 0);
	ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 2, 20); 
	
}

task Spawn{
	let obj = GetPlayerObjectID;
	let y = 0;
	ObjRender_SetX(obj, GetStgFrameWidth/2);
	ObjRender_SetY(obj, GetStgFrameHeight-32);
	SetPlayerSpeed(0,0);
	IsPlayerSpawning = true;
	while(y<82){
		SetPlayerClip(11,11,GetStgFrameWidth-11,GetStgFrameHeight+64);	
		SetPlayerSpeed(0,0);
		ObjRender_SetY(obj, GetStgFrameHeight+32-y);
		y+=2;
		yield;
	}
	IsPlayerSpawning = false;
	SetPlayerSpeed(unshiftspd,shiftspd);
}

task CheckForAreaCommonData{
	let cd = 25;
	while(cd>0){cd--;yield;}
	if(GetAreaCommonData("CirnoPlayer", "SystemType", "Default_System")=="Cirno_System"){
		FreezeInc = 0.04;
	}
}

task RenderPlayerImage(ObjectRender, offset){
	let anim_count = 0;
	let anim_type = 0;
	let Uber = 0;
	let Uberblink = 0;
	let image2alpha = 0;
	
	let x = 32;
	let y = 48;
	let ri = 6;
	let rm = 4;
	let bn = 0;
	
	if(offset==1){
		ObjPrim_SetTexture(objPlayer1, imgPlayer);
		ObjectRender=objPlayer1;
		Obj_SetRenderPriority(ObjectRender, 0.45);
	}
	if(offset==2){
		ObjPrim_SetTexture(objPlayer2, imgPlayer2);
		ObjectRender=objPlayer2;
		ObjRender_SetAlpha(ObjectRender, 225);
		ObjRender_SetScaleXYZ(ObjectRender, 1.35, 1.35, 1);
		Obj_SetRenderPriority(ObjectRender, 0.43);
	}
	
	while(!Obj_IsDeleted(ObjectRender)){
		ObjRender_SetPosition(ObjectRender, GetPlayerX, GetPlayerY, 0);
		
		
		if(!IsPlayerSpawning){
			Blink;
			if(GetVirtualKeyState(VK_RIGHT) == KEY_FREE && GetVirtualKeyState(VK_LEFT) == KEY_FREE){
				if(anim_type != 0){
					bn = 0;
					anim_count = 0;
					anim_type = 0;
				}
			}
			if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH || GetVirtualKeyState(VK_LEFT) == KEY_HOLD){
				if(GetVirtualKeyState(VK_RIGHT) != KEY_HOLD && anim_type != 1){
					bn = 0.85;
					anim_count = 0;
					anim_type = 1;
				}
			}
			if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH || GetVirtualKeyState(VK_RIGHT) == KEY_HOLD){
				if(anim_type != 2){
					bn = 0.85;
					anim_count = 0;
					anim_type = 2;
				}
			}
			anim_count+=(1+bn);
			if(floor(anim_count) != anim_count && bn == 0){
				anim_count = floor(anim_count);
			}
		}else{
			Blink;
			anim_count+=1;
			if(anim_type != 0){
				anim_count = 0;
				anim_type = 0;
			}
		}
		if(GetCirnoState!=STATE_DOWN){
			ObjRender_SetAlpha(ObjectRender, 255);
		}
		if(offset==2){
			if(FreezeMeter<100){image2alpha=FreezeMeter*2;ObjRender_SetColor(ObjectRender, 119, 221, 255);}
			if(FreezeMeter>99){image2alpha=225;ObjRender_SetColor(ObjectRender, 95, 166, 55);}
			ObjRender_SetAlpha(ObjectRender, image2alpha);
		}
		if(GetCirnoState==STATE_DOWN || playerdead){ObjRender_SetAlpha(ObjectRender, 0);}
		
		
		
		
		
		//0 - Idle; 1 - Left; 2 - Right;
		if(anim_type==0){
			if(round(anim_count) >= 0){ObjSprite2D_SetSourceRect(ObjectRender, 0, 0, x, y);}
			if(round(anim_count) >= ri){ObjSprite2D_SetSourceRect(ObjectRender, x, 0, x*2, y);}
			if(round(anim_count) >= ri*2){ObjSprite2D_SetSourceRect(ObjectRender, x*2, 0, x*3, y);}
			if(round(anim_count) >= ri*3){ObjSprite2D_SetSourceRect(ObjectRender, x*3, 0, x*4, y);}
			if(round(anim_count) >= ri*4){ObjSprite2D_SetSourceRect(ObjectRender, x*4, 0, x*5, y);}
			if(round(anim_count) >= ri*5){ObjSprite2D_SetSourceRect(ObjectRender, x*5, 0, x*6, y);}
			if(round(anim_count) >= ri*6){ObjSprite2D_SetSourceRect(ObjectRender, x*6, 0, x*7, y);}
			if(round(anim_count) >= ri*7){ObjSprite2D_SetSourceRect(ObjectRender, x*7, 0, x*8, y);}
			if(round(anim_count) >= ri*8-1){anim_count = ri-1;}
		}
		if(anim_type==1){
			if(round(anim_count) >= 0){ObjSprite2D_SetSourceRect(ObjectRender, 0, y, x, y*2);}
			if(round(anim_count) >= rm){ObjSprite2D_SetSourceRect(ObjectRender, x, y, x*2, y*2);}
			if(round(anim_count) >= rm*2){ObjSprite2D_SetSourceRect(ObjectRender, x*2, y, x*3, y*2);}
			if(round(anim_count) >= rm*3){ObjSprite2D_SetSourceRect(ObjectRender, x*3, y, x*4, y*2);}
			if(round(anim_count) >= rm*4){ObjSprite2D_SetSourceRect(ObjectRender, x*4, y, x*5, y*2);bn = 0}
			if(round(anim_count) >= rm*5){ObjSprite2D_SetSourceRect(ObjectRender, x*5, y, x*6, y*2);}
			if(round(anim_count) >= rm*6){ObjSprite2D_SetSourceRect(ObjectRender, x*6, y, x*7, y*2);}
			if(round(anim_count) >= rm*7){ObjSprite2D_SetSourceRect(ObjectRender, x*7, y, x*8, y*2);}
			if(round(anim_count) >= rm*8-1){anim_count = rm*4-1;}
		}
		if(anim_type==2){
			if(round(anim_count) >= 0){ObjSprite2D_SetSourceRect(ObjectRender, 0, y*2, x, y*3);}
			if(round(anim_count) >= rm){ObjSprite2D_SetSourceRect(ObjectRender, x, y*2, x*2, y*3);}
			if(round(anim_count) >= rm*2){ObjSprite2D_SetSourceRect(ObjectRender, x*2, y*2, x*3, y*3);}
			if(round(anim_count) >= rm*3){ObjSprite2D_SetSourceRect(ObjectRender, x*3, y*2, x*4, y*3);}
			if(round(anim_count) >= rm*4){ObjSprite2D_SetSourceRect(ObjectRender, x*4, y*2, x*5, y*3);bn = 0}
			if(round(anim_count) >= rm*5){ObjSprite2D_SetSourceRect(ObjectRender, x*5, y*2, x*6, y*3);}
			if(round(anim_count) >= rm*6){ObjSprite2D_SetSourceRect(ObjectRender, x*6, y*2, x*7, y*3);}
			if(round(anim_count) >= rm*7){ObjSprite2D_SetSourceRect(ObjectRender, x*7, y*2, x*8, y*3);}
			if(round(anim_count) >= rm*8-1){anim_count = rm*4-1;}
		}
		ObjSprite2D_SetDestCenter(ObjectRender);
		yield;
	}
	task Blink{
		if(GetPlayerInvincibilityFrame>0&&offset==1){
			if(Uber==0){ObjRender_SetColor(ObjectRender, 255, 255, 255);}
			if(Uber!=0){ObjRender_SetColor(ObjectRender, 32, 32, 255);}
			Uberblink+=1;
			if(Uberblink>1){Uberblink=0;Uber++;if(Uber>1){Uber=0}}
		}else{
			ObjRender_SetColor(ObjectRender, 255, 255, 255);
		}
	}
}

task RenderHitboxImage(plobj, offx, hitboxnum){
	yield;yield;yield;
	while(IsPlayerSpawning||playerdead){
		if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_HOLD){return;}
		yield;
	}
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.39);
	ObjRender_SetAlpha(obj, 235);
	ObjPrim_SetTexture(obj, imgPlayer);
	ObjSprite2D_SetSourceRect(obj, 64, 224, 127, 287);
	ObjSprite2D_SetDestCenter(obj);
	
	let obj2 = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj2, BLEND_ALPHA);
	Obj_SetRenderPriority(obj2, 0.69);
	ObjRender_SetAlpha(obj2, 235);
	ObjPrim_SetTexture(obj2, imgPlayer);
	ObjSprite2D_SetSourceRect(obj2, 64, 224, 127, 287);
	ObjSprite2D_SetDestCenter(obj2);
	
	
	let ObjTime = 0;
	
	let AlphaSet = 0;
	let ObjAlpha = 0;
	let ObjScale = 1;
	
	while(GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD&&ObjScale<1.4&&!playerdead){
		ObjTime+=8;
		ObjScale += 0.125;
		PositionSet;
		yield;
	}
	while(GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD&&ObjScale>1&&!playerdead){
		ObjTime+=8;
		ObjScale -= 0.1;
		PositionSet;
		yield;
	}
	ObjScale = 1;
	yield;
	while(GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD&&!playerdead){
		ObjTime+=3;
		PositionSet;
		yield;
	}
	
	while(ObjScale>0){
		ObjTime+=3;
		ObjScale -= 0.1;
		PositionSet;
		yield;
	}

	Obj_Delete(obj);
	Obj_Delete(obj2);
	
	task PositionSet{
		if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH){ObjScale = 0;}
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetAngleZ(obj, ObjTime);
		ObjRender_SetPosition(obj2, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, ObjScale, ObjScale, ObjScale);
		ObjRender_SetScaleXYZ(obj2, ObjScale, ObjScale, ObjScale);
	}
	
}

task DeathExplosion{
	
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA );
	Obj_SetRenderPriority(obj, 0.60);
	ObjPrim_SetTexture(obj, imgPlayer);
	ObjSprite2D_SetSourceRect(obj, 198, 232, 262, 296);
	ObjSprite2D_SetDestRect(obj, -32, -32, 32, 32);

	let alpha = 200;
	let scale = 0;
	let expo = 0.4;
	loop(40){
		scale += expo;
		alpha -= 5;
		if(expo>0){expo = expo^1.07;}
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		yield;
	}
	yield;Obj_Delete(obj);
}


task MapleLeaf(deX, deY, angX, deAlpha, deScale){
	deScale = deScale*1.25;
		let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D); 
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.49);
	ObjPrim_SetTexture(obj, imgPlayer);
	ObjSpriteList2D_SetSourceRect(obj, 0, 144, 32, 176);
	ObjSpriteList2D_SetDestCenter(obj);
	ObjRender_SetAngleXYZ(obj, 0, 0, angX);
	ObjRender_SetPosition(obj, deX, deY, 0);
	ObjRender_SetAlpha(obj, deAlpha);

	let scale = deScale;
	let randX = rand(-105, 105);
	let randY = rand(-105, 105);
	let	ang2 = rand(0, 360);
	
	while(scale>0.01){
		scale += ((-0.2)/2);
		deX += (randX/20);
		deY += (randY/20);
		angX += (randX/15);
		ang2 += (randX/15);
		ObjSpriteList2D_ClearVertexCount(obj);
		ObjSpriteList2D_SetSourceRect(obj, 0, 144, 32, 176);
		ObjSpriteList2D_SetDestCenter(obj);
		ObjSpriteList2D_AddVertex(obj);
		
		ObjRender_SetPosition(obj, deX, deY, 0);
		ObjRender_SetAngleXYZ(obj, ang2, angX, (ang2+angX)/2);
		ObjRender_SetScaleXYZ(obj, scale, scale, scale);
		ObjRender_SetAlpha(obj, deAlpha-scale*20);
		yield;
	}
	Obj_Delete(obj);
}


task BrokenIce(deX, deY){
	let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D); 
	let speed = GetCommonData("StageDiffic", 32)/60+0.45;
	let angle = rand(0,360);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, GetShotRenderPriorityI);
	ObjPrim_SetTexture(obj, imgPlayer);
	ObjSpriteList2D_SetSourceRect(obj, 0, 172, 12, 184);
	ObjSpriteList2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, deX, deY, 0);
	Obj_SetValue(obj, "CirnoGraze", false);
	IceBullets = IceBullets~[obj];
	while(!Obj_IsDeleted(obj)){
		ObjSpriteList2D_ClearVertexCount(obj);
		ObjSpriteList2D_AddVertex(obj);
		deX = ObjRender_GetX(obj);
		deY = ObjRender_GetY(obj);
		ObjRender_SetPosition(obj, deX+speed*cos(angle), deY+speed*sin(angle), 0);
		if(GetPlayerInvincibilityFrame==0){
			if(GetDistance(deX,deY,GetPlayerX,GetPlayerY)<=40&&!Obj_GetValue(obj, "CirnoGraze")){
				Obj_SetValue(obj, "CirnoGraze", true);
				AddGraze(1);
				NotifyEvent(GetOwnScriptID, EV_GRAZE, 1);
			}
			if(GetDistance(deX,deY,GetPlayerX,GetPlayerY)<=5&&GetCirnoState==STATE_NORMAL){
				GetCirnoState = STATE_HIT;
				NotifyEvent(GetOwnScriptID, EV_HIT, true);
				Obj_Delete(obj);
			}
		}
		if(CheckOutsideScreen(obj, 4)){Obj_Delete(obj);}
		yield;
	}
	ObjShot_BulletBreak(deX, deY, 255, 255, 255);
	
	ascent(i in 0..length(IceBullets)-1){
		if(IceBullets[i]==obj){IceBullets = erase(IceBullets, i);}
	}
}



task ClearEnemyBullets(x, y, Tsize, Tspd, Tmaxrad, delay){
	let barray = GetShotIdInCircleA2(x, y, Tsize, TARGET_ENEMY)~GetBrokenIceCircleA1(x, y, Tsize);
	
	loop(delay){yield;}
	if(GetCirnoState==STATE_NORMAL){return;}
	while(Tsize<Tmaxrad){
		barray = GetShotIdInCircleA2(x, y, Tsize, TARGET_ENEMY)~GetBrokenIceCircleA1(x, y, Tsize);
		ascent(i in 0..length(barray)){
			let o = barray[i];
			if(!ObjShot_IsSpellResist(o)){Obj_Delete(o);}
		}
		Tsize += Tspd;
		yield;
	}
}

function GetBrokenIceCircleA1(x, y, size){
	let icelist = [];
	ascent(i in 0..length(IceBullets)){
		if(GetDistance(x, y, ObjRender_GetX(IceBullets[i]), ObjRender_GetY(IceBullets[i])) < size){
			icelist = icelist ~ [IceBullets[i]];
		}
	}
	return icelist;
}


task PerfectFreeze{
	let objManage = GetSpellManageObject;
	let TotalSpellTime = 125;
	let Master_Time = 0;
	
	ScreenShake(TotalSpellTime, 4);
	SetPlayerInvincibilityFrame(265);
	IcicleField;
	Shadow(0.75, 60, 1, 1, 1);
	ObjSound_Play(spellsnd);

	
	loop(TotalSpellTime){
		SetPlayerSpeed(unshiftspd/2,shiftspd/2);
		FreezeCharge = 0;
		Master_Time++;
		yield;
	}
	FreezeScene = 2;
	IceBarrierMain;
	FreezeBullets(GetPlayerX, GetPlayerY, 750, 3, true);
	
	ObjSound_Stop(spellsnd);
	PlaySE(current~"se_ice.wav");
	SetPlayerSpeed(unshiftspd,shiftspd);
	Obj_Delete(objManage);
		
	task Shadow(incremental, alpha, colorR, colorG, colorB){
	
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		let BombTime = 0;
		let xBend = 1;
		let yBend = 1;
		let BendInc = 0.22;
		let BombSet = 0;
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.30);
		ObjRender_SetAlpha(obj, alpha);
		ObjPrim_SetTexture(obj, imgPlayer);
		ObjSprite2D_SetSourceRect(obj, 0, 234, 62, 296);
		ObjSprite2D_SetDestRect(obj, -xBend, -xBend, xBend, xBend);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetColor(obj, colorR, colorG, colorB);

		while(Obj_IsDeleted(obj) == false){
			BombTime++;
			ObjSprite2D_SetDestRect(obj, -xBend, -xBend, xBend, xBend);
			
			if(xBend<1500&&BombSet==0){
				xBend+=BendInc;
				BendInc+=incremental;
			}
			if(BombTime>TotalSpellTime&&BombSet==0){
				Obj_Delete(obj);
			}
			yield;
		}
	}
	task IcicleField{
		
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		let obj_time = 0;
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.29);
		ObjPrim_SetTexture(obj, imgField);
		ObjSprite2D_SetSourceRect(obj, 0, 0, 2048, 2048);
		ObjSprite2D_SetDestRect(obj, -148, -148, 1900, 1900);
		ObjRender_SetAngleXYZ(obj, 0, 0, 0);
		ObjRender_SetPosition(obj, 0, 0, 0);
		
		let alpha = 0;
		while(Obj_IsDeleted(objManage)==false){
			obj_time--;
			if(alpha<255){alpha+=3+alpha/145;}
			ObjRender_SetAlpha(obj, alpha);
			ObjRender_SetPosition(obj, obj_time*4, obj_time*2.5, 0);
			yield;
		}	
		Obj_Delete(obj);
	}

	task ScreenShake(shaketime, intensity){
		let x = Get2DCameraX;
		let y = Get2DCameraY;
		while(shaketime>0){
			Set2DCameraFocusX(x + rand(-intensity, intensity));
			Set2DCameraFocusY(y + rand(-intensity, intensity));
			shaketime--;
			yield;
		}
		Set2DCameraFocusX(x);
		Set2DCameraFocusY(y);
		yield;
	}

}

task CreateLevelUp(level){	
	CreateCircleA1(GetPlayerObjectID, 96, 96, 1, 64, 16, 208, 255);
	CreateCircleA1(GetPlayerObjectID, 64, 64, 0.66, 64, 16, 208, 255);
	CreateCircleA1(GetPlayerObjectID, 32, 32, 0.33, 64, 16, 208, 255);
}

task CirnoShotType{
	let shotCount = 1;
	let loopCount = 0;
	let CircleShoot = 0;
	yield;
	while(CanShoot == false){yield;}
	let CirnoLevel = GetPlayerPower;
	loop{
		FireShotData;
		PlayerShoot;
		if(CirnoLevel<floor(GetPlayerPower)&&CirnoLevel<11){
			PlaySE(current~"se_powerup.wav");
			CirnoLevel = floor(GetPlayerPower);
			CreateLevelUp(CirnoLevel);
		}
		else{
			CirnoLevel = truncate(GetPlayerPower);
		}
		yield;
	}
	
	task FireShotData{
		if(GetVirtualKeyState(VK_SHOT)==KEY_PUSH || GetVirtualKeyState(VK_SHOT)==KEY_HOLD && CanShoot == true){
			loopCount = 1;
			FreezeCharge++;
		}
		if(GetVirtualKeyState(VK_USER1)==KEY_PUSH || GetVirtualKeyState(VK_USER1)==KEY_HOLD){
			if(GetVirtualKeyState(VK_SHOT)==KEY_FREE){
				loopCount = 1;
			}
		}
		
		if(loopCount>0){
			loopCount++;
			shotCount--;
			if(loopCount>28||IsPlayerSpawning){
				loopCount = 0;
				shotCount = 1;
				CircleShoot = 5;
				FreezeCharge = 0;
			}
		}
		
		if(shotCount<0){shotCount = 3;}
		
		if(FreezeCharge==FreezeBeginCharge){ObjSound_Play(chargesnd);}
		if(FreezeCharge==FreezeEndCharge && FreezeMeter>=30){ObjSound_Stop(chargesnd); PlaySE(current~"se_charged.wav");}
		if(FreezeCharge>FreezeEndCharge && floor(FreezeMeter)==30){ObjSound_Stop(chargesnd); PlaySE(current~"se_charged.wav");PlaySE(current~"se_pin00.wav");AddToCharge(1);}
		if(GetVirtualKeyState(VK_SHOT)==KEY_PULL){
			ObjSound_Stop(chargesnd);
			if(FreezeCharge>=FreezeEndCharge && FreezeMeter>=30){IceBarrierMain}
			FreezeCharge=0;
		}
	}
	
	task PlayerShoot{		
		if(shotCount == 0 && CanShoot == true && FreezeCharge<FreezeBeginCharge){
			PlaySE(current~"se_shot.wav");
			CircleShoot++;
			if(CirnoLevel<=1){
				ShotCount = 2;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 4, 1, 1);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 4, 1, 1);
			}
			if(CirnoLevel==2){
				ShotCount = 2;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 4.5, 1, 2);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 4.5, 1, 2);
			}
			if(CirnoLevel==3){
				ShotCount = 4;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.5, 1, 2);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.5, 1, 2);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.5, 1, 2);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.5, 1, 2);
			}
			if(CirnoLevel==4){
				ShotCount = 6;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1, 1, 2);
			}
			if(CirnoLevel==5){
				ShotCount = 8;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1, 1, 2);
			}
			if(CirnoLevel==6){
				ShotCount = 10;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2, 1, 2);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2, 1, 2);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2, 1, 2);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1, 1, 2);
			}
			if(CirnoLevel==7){
				ShotCount = 10;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1, 1, 2);
			}
			if(CirnoLevel==8){
				ShotCount = 10;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1.5, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1.5, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1, 1, 2);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1, 1, 2);
			}
			if(CirnoLevel==9){
				ShotCount = 10;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1.5, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1.5, 1, 3);
			}
			if(CirnoLevel==10){
				ShotCount = 12;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1.25, 1, 3);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 258, 1, 1, 3);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 282, 1, 1, 3);
			}
			if(CirnoLevel>=11){
				ShotCount = 12;
				CreateCirnoShotA1(GetPlayerX-9, GetPlayerY-16, 15, 270, 2.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX+11, GetPlayerY-16, 15, 270, 2.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX-19, GetPlayerY-16, 15, 270, 2.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX+21, GetPlayerY-16, 15, 270, 2.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 265, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 275, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 280, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 260, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 275, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 265, 1.35, 1, 4);
				CreateCirnoShotA1(GetPlayerX-16, GetPlayerY-16, 15, 258, 1.15, 1, 4);
				CreateCirnoShotA1(GetPlayerX+20, GetPlayerY-16, 15, 282, 1.15, 1, 4);
				if(CircleShoot>6){
					ascent(i in 0..8){
						CreateCirnoShotA1(GetPlayerX, GetPlayerY, 15, (360/8)*i, 6, 1, 2);
					}
					CircleShoot=0;
				}
			}
		}
	}
}

task CreateCircleA1(objid, siz, esiz, sinc, destsiz, r, g, b){
	let alpha = 0;
	let countVertex = 33;
	
	let circ = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetPrimitiveType(circ, PRIMITIVE_TRIANGLEFAN);
	ObjPrim_SetTexture(circ, NULL);
	Obj_SetRenderPriority(circ, 0.60);
	ObjPrim_SetVertexCount(circ, countVertex);
	ObjRender_SetBlendType(circ, BLEND_ALPHA);
	
	
	ObjPrim_SetVertexUVT(circ, 0, 0, 0);	
	ObjPrim_SetVertexPosition(circ, 0, 0, 0, 0);
	ObjPrim_SetVertexColor(circ, 0, 255, 255, 255);
	ObjPrim_SetVertexAlpha(circ, 0, 0);
	let x = ObjRender_GetX(objid);
	let y = ObjRender_GetY(objid);
	ObjRender_SetPosition(circ, x, y, 0);
	
	ascent(iVert in 1..countVertex){
		let angle = (360 / (countVertex - 2) * iVert);
		ObjPrim_SetVertexUVT(circ, iVert, 0, 0);	
		let x = siz*cos(angle);
		let y = siz*sin(angle);
		ObjPrim_SetVertexPosition(circ, iVert , x, y, 0);
		ObjPrim_SetVertexColor(circ, iVert, r, g, b);
		ObjPrim_SetVertexAlpha(circ, iVert, alpha);
	}
	while(siz > esiz/8){
		alpha = min(alpha + 5, 128);
		if(!Obj_IsDeleted(objid)){
			x = ObjRender_GetX(objid);
			y = ObjRender_GetY(objid);
		}
		ObjRender_SetPosition(circ, x, y, 0);
		siz -= sinc;
		ascent(iVert in 1..countVertex){
			let angle = (360 / (countVertex - 2) * iVert);
			ObjPrim_SetVertexPosition(circ, iVert , (siz+8)*cos(angle), (siz+8)*sin(angle), 0);
			ObjPrim_SetVertexAlpha(circ, iVert, alpha);
		}
		yield;
	}
	while(alpha>0){
		alpha -= 10;
		if(!Obj_IsDeleted(objid)){
			x = ObjRender_GetX(objid);
			y = ObjRender_GetY(objid);
		}
		ObjRender_SetPosition(circ, x, y, 0);
		siz -= sinc;
		ascent(iVert in 1..countVertex){
			let angle = (360 / (countVertex - 2) * iVert);
			ObjPrim_SetVertexPosition(circ, iVert , (siz+8)*cos(angle), (siz+8)*sin(angle), 0);
			ObjPrim_SetVertexAlpha(circ, iVert, alpha);
		}
		yield;
	}
	Obj_Delete(circ);
}



	
task CreateCirnoShotA1(ShotX, ShotY, Shotspd, Shotangle, Shotdmg, Shotpenetration, Shotgraphic){
	let ShotObj = CreatePlayerShotA1(ShotX, ShotY, Shotspd, Shotangle, Shotdmg, Shotpenetration, Shotgraphic);
	let X = 0;
	let Y = 0;
	let A = 0;
	while(Obj_IsDeleted(ShotObj)==false){
		X = ObjRender_GetX(ShotObj);
		Y = ObjRender_GetY(ShotObj);
		A = ObjMove_GetAngle(ShotObj);
		yield;
	}
	if(X>1 && Y >1){ShotHit(X, Y-8, A, Shotgraphic);SetPlayerLife(GetPlayerLife+0.00000145);}
}
task CreateCirnoShotA2(ShotX, ShotY, Shotspd, Shotangle, Shotdmg, Shotpenetration, Shotgraphic, delay){
	let ShotObj = CreatePlayerShotA1(ShotX, ShotY, Shotspd, Shotangle, Shotdmg, Shotpenetration, Shotgraphic);
	while(delay>0 && !Obj_IsDeleted(ShotObj)){
		delay--;
		yield;
	}
	if(delay>0){SetPlayerLife(GetPlayerLife+0.00000645);}
	if(!Obj_IsDeleted(ShotObj)){Obj_Delete(ShotObj)}
}

task ShotHit(EffectX, EffectY, EffectA, type){
	let obj3 = ObjPrim_Create(OBJ_SPRITE_2D);
	let obj3angle = 0;
	let obj3_time = 0;
	AddToCharge(1.25/ShotCount);
	ObjRender_SetBlendType(obj3, BLEND_ALPHA);
	ObjRender_SetAlpha(obj3, 105);
	Obj_SetRenderPriority(obj3, 0.59);
	ObjPrim_SetTexture(obj3, imgBullet);
	if(type==1){
		ObjSprite2D_SetSourceRect(obj3, 1, 200, 18, 218);
		ObjSprite2D_SetDestRect(obj3, -9, -9, 9, 9);
	}
	if(type==2){
		ObjSprite2D_SetSourceRect(obj3, 17, 111, 35, 170);
		ObjSprite2D_SetDestRect(obj3, -9, -29, 9, 29);
	}
	if(type==3){
		ObjSprite2D_SetSourceRect(obj3, 34, 112, 57, 172);
		ObjSprite2D_SetDestRect(obj3, -11.5, -30, 11.5, 30);
	}
	if(type==4){
		ObjSprite2D_SetSourceRect(obj3, 58, 112, 81, 172);
		ObjSprite2D_SetDestRect(obj3, -11.5, -30, 11.5, 30);
	}
	ObjRender_SetAlpha(obj3, 125);
	ObjRender_SetAngleZ(obj3, EffectA+90);
	ObjRender_SetX(obj3, EffectX-1);
	ObjRender_SetY(obj3, EffectY);
	
	while(Obj_IsDeleted(obj3)==false){
		obj3_time++;
		if(obj3_time==3){
			if(type==1){ObjSprite2D_SetSourceRect(obj3, 1, 183, 18, 201);}
			if(type==2){ObjSprite2D_SetSourceRect(obj3, 16, 52, 34, 112);}
			if(type==3){ObjSprite2D_SetSourceRect(obj3, 34, 52, 57, 112);}
			if(type==4){ObjSprite2D_SetSourceRect(obj3, 58, 52, 81, 112);}
		}
		if(obj3_time==6){
			if(type==1){ObjSprite2D_SetSourceRect(obj3, 1, 166, 18, 184);}
			if(type==2){ObjSprite2D_SetSourceRect(obj3, 16, 3, 34, 50);ObjSprite2D_SetDestRect(obj3, -9, -23, 9, 23);}
			if(type==3){ObjSprite2D_SetSourceRect(obj3, 35, 4, 58, 50);ObjSprite2D_SetDestRect(obj3, -11.5, -23, 11.5, 23);}
			if(type==4){ObjSprite2D_SetSourceRect(obj3, 58, 4, 81, 50);ObjSprite2D_SetDestRect(obj3, -11.5, -23, 11.5, 23);}
		}
		if(obj3_time==9){Obj_Delete(obj3);}
		ObjRender_SetPosition(obj3, ObjRender_GetX(obj3)+5*cos(EffectA), ObjRender_GetY(obj3)+5*sin(EffectA), 0);
		yield;
	}
}


function FreezeBullets(fbX, fbY, radius, fbtype, BombFreezer){
	let barray = GetShotIdInCircleA2(fbX, fbY, radius, TARGET_ENEMY);
	let blength = length(barray);
	if(!BombFreezer && fbtype == 2){blength = min(CheckBulletMax, blength)}
	let islaserexist = ID_INVALID; 
	if(AllowFreeze && blength>0){
		ascent (i in 0..blength){
			if(!Obj_IsValueExists(barray[i], "gt_CirnoA_Frozen")){
				let s = ObjShot_GetImageID(barray[i]);
				if(IsAllowFreeze(barray[i])){
					if(ObjLaser_GetLength(barray[i])==0 && !ObjShot_IsSpellResist(barray[i])){
						let bX =  ObjRender_GetX(barray[i]);
						let bY = ObjRender_GetY(barray[i]);
						CreateBulletIcicle(bX, bY, s, barray[i]);
					}
					if(ObjLaser_GetLength(barray[i])!=0){
						islaserexist = barray[i];
					}
				}
			}
		}
	}
	return islaserexist;
	function IsAllowFreeze(id){
		let iafv = true;
		if(ObjShot_GetImageID(id)==162||ObjShot_GetImageID(id)==163||Obj_IsValueExists(id, "Fireball")){
			iafv = false;
		}
		if(BombFreezer){iafv = true;}
		return iafv;
	}
	task CreateBulletIcicle(x, y, ID, bID){
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		Obj_SetRenderPriority(obj, 0.39);
		ObjPrim_SetTexture(obj, RenderToTextureB1(GetReservedRenderTargetName(2), bID, true));
		ObjSprite2D_SetDestRect(obj, -8, -8, 8, 8);
		ObjSprite2D_SetDestCenter(obj);
		ObjRender_SetX(obj, x);
		ObjRender_SetY(obj, y);
		ObjRender_SetColor(obj, 205, 205, 255);
		
		if(Obj_IsValueExists(bID, "MediumBullet")){
			IceBarrierLarge(x, y, round(rand(1,4)), obj);
			return;
		}
		if(Obj_IsValueExists(bID, "SmallBullet")){
			IceBarrierMedium(x, y, round(rand(1,4)), obj);
			return;
		}
		
		if(CheckID(25, 32, ID) || CheckID(225, 232, ID) || CheckID(165, 172, ID)
		|| CheckID(181, 184, ID) || CheckID(217, 220, ID)){
			IceBarrierLarge(x, y, round(rand(1,4)), obj);
		}	
		else{
			IceBarrierMedium(x, y, round(rand(1,4)), obj);
		}
		
		Obj_Delete(bID);
	}
	function CheckID(num1, num2, id){
		return id >= num1 && id <= num2;
	}
}

task IceBarrierMain{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objangle = 0;
	let obj_time = 0;
	let size = 50;
	
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriority(obj, 0.42);
	ObjPrim_SetTexture(obj, imgEffect);
	ObjSprite2D_SetSourceRect(obj, 66, 161, 161, 256);
	ObjSprite2D_SetDestRect(obj, -size, -size, size, size);
	ObjRender_SetAngleZ(obj, rand(0,360));
	ObjRender_SetX(obj, GetPlayerX);
	ObjRender_SetY(obj, GetPlayerY);
	ObjRender_SetColor(obj, 170, 170, 170);
	
	if(FreezeScene == 0){
		FreezeScene = 1;
		FreezeTime = FreezeMeter*1.4;
		FreezeMeter = 0;
	}
	if(FreezeScene == 2){
		FreezeTime = 75;
	}
	
	PlaySE(current~"se_spell.wav");
	
	loop(3){IceParticle(ObjRender_GetX(obj), ObjRender_GetY(obj), rand(0,360), 1.5);}
	
	SetAreaCommonData("CirnoPlayer", "IceBarrierUse", GetAreaCommonData("CirnoPlayer", "IceBarrierUse", 0)+1);
	
	while(FreezeScene == 1 || FreezeScene == 2){
		FreezeTime--;
		if(FreezeTime<1){FreezeScene=0;}
		obj_time++;
		
		if(obj_time<5){
			size += -0.5;
			ObjSprite2D_SetDestRect(obj, -size, -size, size, size);
		}
		if(obj_time==5){
			ObjSprite2D_SetDestRect(obj, -47.5, -47.5, 47.5, 47.5);
			ObjSprite2D_SetSourceRect(obj, 162, 162, 256, 256);
		}
		let icecolor = 185+sin(ObjRender_GetY(obj)-ObjRender_GetX(obj)+FreezeTime*4)*65;
		ObjRender_SetColor(obj, icecolor, icecolor, icecolor);
		FreezeBullets(ObjRender_GetX(obj), ObjRender_GetY(obj), 45, 1, false);
		yield;
	}
	loop(3){IceParticle(ObjRender_GetX(obj), ObjRender_GetY(obj), rand(0,360), 1);}
	PlaySE(current~"se_ice2.wav");
	EndFreezeScene(ObjRender_GetX(obj), ObjRender_GetY(obj), "main");
	Obj_Delete(obj);
}

task IceBarrierMedium(x, y, type, bID){
	PlaySE(current~"se_ice.wav");
	IceParticle(x, y, rand(0,360), 1);
	if(GetDistance(x,y,LastFreezeX,LastFreezeY) < 14){
		ObjRender_SetAngleZ(LastFreezeID, rand(0,360));
		//Obj_Delete(bID);
		return;
	}

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriority(obj, 0.42);
	ObjPrim_SetTexture(obj, imgEffect);
	ObjRender_SetAngleZ(obj, rand(0,360));
	ObjRender_SetX(obj, x);
	ObjRender_SetY(obj, y);
	ObjRender_SetColor(obj, 170, 170, 170);
	
	LastFreezeX = x;
	LastFreezeY = y;
	LastFreezeID = obj;
	
	if(type==1){ObjSprite2D_SetSourceRect(obj, 128, 129, 160, 160);}
	if(type==2){ObjSprite2D_SetSourceRect(obj, 160, 129, 192, 160);}
	if(type==3){ObjSprite2D_SetSourceRect(obj, 192, 129, 224, 160);}
	if(type==4){ObjSprite2D_SetSourceRect(obj, 224, 129, 256, 160);}
	
	let size = -16;
	while(size!=0){
		size+= 4;
		ObjSprite2D_SetDestRect(obj, -16-size, -16-size, 16+size, 16+size);
		yield;
	}
	
	if(type==1){ObjSprite2D_SetSourceRect(obj, 0, 129, 32, 160);}
	if(type==2){ObjSprite2D_SetSourceRect(obj, 32, 129, 64, 160);}
	if(type==3){ObjSprite2D_SetSourceRect(obj, 64, 129, 96, 160);}
	if(type==4){ObjSprite2D_SetSourceRect(obj, 96, 130, 128, 159);}
	ObjSprite2D_SetDestRect(obj, -16, -16, 16, 16);
	
	let l = ID_INVALID;
	while(FreezeScene!=0 && !Obj_IsDeleted(obj)){
		ObjShot_SetIntersectionEnable(bID, false);
		l = FreezeBullets(ObjRender_GetX(obj), ObjRender_GetY(obj), 20, 2, false);
		if(l != ID_INVALID){
			loop(2){BrokenIce(ObjRender_GetX(obj), ObjRender_GetY(obj));}
			Obj_Delete(obj);
		}
		let icecolor = 185+sin(ObjRender_GetY(obj)-ObjRender_GetX(obj)+FreezeTime*4)*65;
		ObjRender_SetColor(obj, icecolor, icecolor, icecolor);
		yield;
	}
	IceParticle(x, y, rand(0,360), 1);
	if(!Obj_IsDeleted(obj)){EndFreezeScene(ObjRender_GetX(obj), ObjRender_GetY(obj), "medium");}
	Obj_Delete(obj);
	Obj_Delete(bID);
}

task IceBarrierLarge(x, y, type, bID){

	PlaySE(current~"se_ice.wav");
	IceParticle(x, y, rand(0,360), 1);
	if(GetDistance(x,y,LastFreezeX,LastFreezeY) < 32){
		ObjRender_SetAngleZ(LastFreezeID, rand(0,360));
		Obj_Delete(bID);
		return;
	}

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriority(obj, 0.42);
	ObjPrim_SetTexture(obj, imgEffect);
	ObjRender_SetAngleZ(obj, rand(0,360));
	ObjRender_SetX(obj, x);
	ObjRender_SetY(obj, y);
	ObjRender_SetColor(obj, 170, 170, 170);
	
	LastFreezeX = x;
	LastFreezeY = y;
	LastFreezeID = obj;
	if(type==1){ObjSprite2D_SetSourceRect(obj, 0, 63, 64, 124);}
	if(type==2){ObjSprite2D_SetSourceRect(obj, 64, 63, 128, 124);}
	if(type==3){ObjSprite2D_SetSourceRect(obj, 128, 63, 192, 124);}
	if(type==4){ObjSprite2D_SetSourceRect(obj, 192, 63, 256, 124);}
	
	let size = -20;
	while(size!=0){
		size+= 4;
		ObjSprite2D_SetDestRect(obj, -32-size, -32-size, 32+size, 32+size);
		yield;
	}
	
	if(type==1){ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 64);}
	if(type==2){ObjSprite2D_SetSourceRect(obj, 64, 0, 128, 64);}
	if(type==3){ObjSprite2D_SetSourceRect(obj, 128, 0, 192, 64);}
	if(type==4){ObjSprite2D_SetSourceRect(obj, 192, 0, 256, 64);}
	ObjSprite2D_SetDestRect(obj, -32, -32, 32, 32);
	
	let l = ID_INVALID;
	while(FreezeScene!=0 && !Obj_IsDeleted(obj)){
		ObjShot_SetIntersectionEnable(bID, false);
		l = FreezeBullets(ObjRender_GetX(obj), ObjRender_GetY(obj), 40, 2, false);
		if(l != ID_INVALID){Obj_SetValue(l, "IceBreak", 1);Obj_Delete(obj);}
		let icecolor = 185+sin(ObjRender_GetY(obj)-ObjRender_GetX(obj)+FreezeTime*4)*65;
		ObjRender_SetColor(obj, icecolor, icecolor, icecolor);
		yield;
	}
	IceParticle(x, y, rand(0,360), 1);
	if(!Obj_IsDeleted(obj)){EndFreezeScene(ObjRender_GetX(obj), ObjRender_GetY(obj), "large");}
	Obj_Delete(obj);
	Obj_Delete(bID);
}

task EndFreezeScene(x, y, size){
	if(size == "main"){SetPlayerPower(GetPlayerPower+0.0220);SetPlayerSpell(GetPlayerSpell+0.01118);}
	if(size == "medium"){SetPlayerPower(GetPlayerPower+0.00095);SetPlayerSpell(GetPlayerSpell+0.00038);}
	if(size == "large"){SetPlayerPower(GetPlayerPower+0.00175);SetPlayerSpell(GetPlayerSpell+0.00068);}
	CreateCirnoShotA2(x, y, 0, 0, 0.5, 3, 5, 15);
	SetAreaCommonData("CirnoPlayer", "IceArea", GetPlayerPower*100);
	SetAreaCommonData("CirnoPlayer", "PerfectFreeze", GetPlayerSpell*100);
}

task IceParticle(deX, deY, angX, deScale){
	if(TotalParticleCount>=MaximumParticles){return;}
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriority(obj, 0.49);
	ObjPrim_SetTexture(obj, imgEffect);
	ObjSprite2D_SetSourceRect(obj, 0, 160, 8, 169);
	ObjSprite2D_SetDestRect(obj, -4, -4.5, 4, 4.5);
	ObjRender_SetAngleXYZ(obj, 0, 0, angX);
	ObjRender_SetPosition(obj, deX, deY, 0);
	ObjRender_SetAlpha(obj, 200);

	let scale = deScale;
	let randX = rand(-500, 500);
	let randY = rand(-500, 500);
	
	TotalParticleCount++;
	while(Obj_IsDeleted(obj)==false){
		scale += -0.05;
		deX += randX/100;
		deY += randY/100;
		angX += randX/85;
		
		ObjRender_SetPosition(obj, deX, deY, 0);
		ObjRender_SetAngleXYZ(obj, 0, 0, angX);
		ObjRender_SetScaleXYZ(obj, scale, scale, scale);
		
		if(scale<0.01){Obj_Delete(obj)}
		yield;
	}
	TotalParticleCount--;
	Obj_Delete(obj);
}

task RenderChargeReady(num){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let ObjTime = 0;
	
	let ObjAlpha = 0;
	let ObjScale = 0.76;
	
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.44);
	ObjRender_SetAlpha(obj, 0);
	ObjPrim_SetTexture(obj, imgCharged);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 128, 128);
	ObjSprite2D_SetDestRect(obj, -64, -64, 64, 64);
	
	
	while(Obj_IsDeleted(obj) == false){
		ObjTime++;
		
		if(FreezeCharge>FreezeBeginCharge){
			if(FreezeCharge<FreezeEndCharge){
				ObjScale = 0.76-FreezeCharge/200;
				ObjAlpha = FreezeCharge*2;
			}
		}else{
			ObjAlpha=0;
		}
		
		ObjRender_SetAngleXYZ(obj, 0, 0, ObjTime*4);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, ObjScale, ObjScale, 0);
		ObjRender_SetAlpha(obj, ObjAlpha);
		
		yield;
	}
}

task AddToCharge(num){
	FreezeMeter = max(0, min(FreezeMeter+num, 100));
}

task DrawFreezeMeterList{
	let count = 3;
	let dummy = 0;
	

	let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
	ObjPrim_SetTexture(obj, imgAscii);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.45);
	ObjRender_SetScaleXYZ(obj, 0.5, 0.5, 0.5);
	ObjRender_SetColor(obj, 172, 202, 238);

	
	let objBomb = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
	ObjPrim_SetTexture(objBomb, imgPlayer);
	Obj_SetRenderPriority(objBomb, 0.7);
	ObjSpriteList2D_SetSourceRect(objBomb, 169, 245, 185, 261);
	
	let fade = 255;
	loop{
		ObjSpriteList2D_ClearVertexCount(objBomb);
		ObjSpriteList2D_ClearVertexCount(obj);
		
		let point = FreezeMeter;
		point = min(point, 100);
		if(FreezeMeter<10){count = 1}
		if(FreezeMeter>=10&&FreezeMeter<100){count = 2}
		if(FreezeMeter == 100){count = 3}
		
		let listNum = DigitToArray(point, count);
		listNum = listNum ~ [10];
		
		ObjRender_SetY(obj, GetPlayerY - 42);
		
		if(GetPlayerX < 16 + (min(9, truncate(GetPlayerSpell)) + 1) * 16 && GetPlayerY > (GetStgFrameHeight-48)){
			fade = max(fade-10, 85);
		}else{fade = min(fade+10, 255);}
		ObjRender_SetAlpha(objBomb, fade);
		if(FreezeMeter<30){ObjRender_SetColor(obj, 135, 135, 135);}else{ObjRender_SetColor(obj, 172, 202, 238);}
		if(count == 1){dummy = -7;}
		if(count == 2){dummy = -14;}
		if(count == 3){dummy = -19;}
		
		ascent(iStep in 0 .. min(9, truncate(GetPlayerSpell))){
			let i = iStep;
			ObjSpriteList2D_SetDestRect(objBomb, 4 + i * 16, (GetStgFrameHeight-8),
				4 + (i + 1) * 16, (GetStgFrameHeight-24));
			ObjSpriteList2D_AddVertex(objBomb);
		}
		
		ascent(iObj in 0 .. count+1){
			let num = listNum[iObj];
			ObjRender_SetX(obj, GetPlayerX + dummy + iObj * 10);
			ObjSpriteList2D_SetSourceRect(obj, num * 24, 0, (num + 1) * 24, 24);
			if(FreezeCharge<FreezeBeginCharge){
				ObjSpriteList2D_SetDestRect(obj, 0, 0, 24, 24);
			}
			if(FreezeCharge>=FreezeEndCharge && FreezeMeter>30){
				ObjRender_SetX(obj, GetPlayerX + dummy - 2 + iObj * 12);
				ObjSpriteList2D_SetDestRect(obj, -6, -6, 24, 24);
			}
			ObjSpriteList2D_AddVertex(obj);
		}
		yield;
	}
}

function DigitToArray(digit, count){
	let res = [];
	digit = truncate(digit);

	loop{
		let tnum = truncate(digit % 10);
		digit /= 10;
		res = [tnum] ~ res;
		if(truncate(digit) == 0){break;}
	}

	loop(max(0, count - length(res))){
		res = [0] ~ res;
	}

	return res;
}

function GetDistance(x1,y1,x2,y2){
	return(((x2-x1)^2+(y2-y1)^2)^(1/2))
}

function CheckOutsideScreen(objectID, distance){	
	return ObjRender_GetX(objectID)>GetStgFrameWidth+distance||ObjRender_GetX(objectID)<-distance||
	ObjRender_GetY(objectID)>GetStgFrameHeight+distance||ObjRender_GetY(objectID)<-distance;
}

task ObjShot_BulletBreak(x, y, r, g, b){
	if(x<0||y<0||x>GetStgFrameWidth||y>GetStgFrameHeight){return;}
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let btime = 0;
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	ObjPrim_SetTexture(obj, imgPlayer);
	Obj_SetRenderPriority(obj, 0.49);
	ObjRender_SetAlpha(obj, 205);
	ObjSprite2D_SetSourceRect(obj, 0, 192, 32, 224);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetColor(obj, r, g, b);
	ObjRender_SetPosition(obj, x+rand(-4,4)*cos(rand(0,360)), y+rand(-4,4)*sin(rand(0,360)), 0);
	ObjRender_SetAngleZ(obj, rand(0,360));
	while(btime<27){
		if(btime==3){ObjSprite2D_SetSourceRect(obj, 32, 192, 64, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==6){ObjSprite2D_SetSourceRect(obj, 64, 192, 96, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==9){ObjSprite2D_SetSourceRect(obj, 96, 192, 128, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==12){ObjSprite2D_SetSourceRect(obj, 128, 192, 160, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==15){ObjSprite2D_SetSourceRect(obj, 128, 192, 160, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==18){ObjSprite2D_SetSourceRect(obj, 160, 192, 192, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==21){ObjSprite2D_SetSourceRect(obj, 192, 192, 224, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		if(btime==24){ObjSprite2D_SetSourceRect(obj, 224, 192, 256, 224);ObjRender_SetAngleZ(obj, rand(0,360));}
		btime++;
		yield;
	}
	Obj_Delete(obj);
}

