#TouhouDanmakufu[Stage]
#ScriptVersion[2]
#Title[Hell's Famous Sisters]
#Text[by Miransu Uwabami
Please see readme.txt before playing]
#Player[.\_PlayerA.txt, .\_PlayerB.txt]

script_stage_main {
	#include_function ".\variables.txt"
	#include_function ".\background.txt"
	#include_function ".\stageintro.txt"
	#include_function ".\bosssys.txt"
	#include_function ".\event.txt"
	#include_function ".\choosediff.txt"
	#include_function ".\stgframe.txt"
	let chosediff = false;
	@Initialize {
		CreateCommonDataArea("Config");
		LoadCommonDataEx("Config", GetCurrentScriptDirectory ~ "config.dat");
		LoadGraphic(bgNon1);
		LoadGraphic(bgNon2);
		LoadGraphic(bgNon3);
		LoadGraphic(bgNon4);
		LoadGraphic(bgSpell1a);
		LoadGraphic(bgSpell1b);
		LoadGraphic(bgSpell2a);
		LoadGraphic(bgSpell2b);
		LoadGraphic(white);
		LoadGraphic(intro);
		LoadGraphic(chargeCircle);
		LoadGraphic(cut);
		LoadGraphic(hudenemy);
		LoadGraphic(lifebarbase);
		LoadGraphic(lifebarwhite);
		LoadGraphic(magicCircle);
		LoadGraphic(numbers);
		LoadGraphic(spellback);
		LoadGraphic(spellnames);
		LoadGraphic(spriteSatori);
		LoadGraphic(spriteKoishi);
		LoadGraphic(shield);
		LoadGraphic(shots);
		LoadGraphic(talk);
		LoadGraphic(talk2);
		LoadGraphic(stgframe);
		LoadMusic(music);
		LoadMusic(musicT);
		SetCommonData("Spell Active", false);
		SetCommonData("Spell Background Type", 0); // 0 = Satori; 1 = Koishi; 2 = Both
		SetCommonData("X Satori", GetCenterX+150);
		SetCommonData("Y Satori", GetClipMinY-96);
		SetCommonData("X Koishi", GetCenterX-150);
		SetCommonData("Y Koishi", GetClipMinY-96);
		SetCommonData("Boss Timer", 0);
		SetCommonData("Boss Timer Max", 1);
		SetCommonData("Life Satori", 0);
		SetCommonData("Life Koishi", 0);
		SetCommonData("Dead Satori", 0);
		SetCommonData("Dead Koishi", 0);
		SetCommonData("Lower Life", 0);
		SetCommonData("Life Master", 0);
		SetCommonData("Life Master Max", 0);
		SetCommonData("Life Type", 0);
		SetCommonData("Life Type Current", 0);
		SetCommonData("Lifebar Length Reset", 0);
		SetCommonData("Being Koishi", false);
		SetCommonData("Ending", false);
		SetCommonData("Chosen Difficulty", false);
		SetCommonData("Difficulty", 1);
		SetClearFrameEffectEnable(false);
		ExpertEx(false, 5, 7);
		SetRateScoreSystemEnable(false);
		SetDefaultStatusVisible(false);
		CreateRenderTarget("spell_line", 128, 16);
		ClearRenderTarget("spell_line");
		SetRenderTarget("spell_line");
		SetTexture(hudenemy);
		SetGraphicRect(128, 48, 256, 64);
		DrawGraphic(64,8);
		SetRenderTarget("DEFAULT");
		KomeijiStage;
		StartSTGFrame;
	}
	@Finalize {
		DeleteGraphic(bgNon1);
		DeleteGraphic(bgNon2);
		DeleteGraphic(bgNon3);
		DeleteGraphic(bgNon4);
		DeleteGraphic(bgSpell1a);
		DeleteGraphic(bgSpell1b);
		DeleteGraphic(bgSpell2a);
		DeleteGraphic(bgSpell2b);
		//DeleteGraphic(white);
		DeleteGraphic(intro);
		DeleteGraphic(chargeCircle);
		DeleteGraphic(cut);
		DeleteGraphic(hudenemy);
		DeleteGraphic(lifebarbase);
		DeleteGraphic(lifebarwhite);
		DeleteGraphic(magicCircle);
		DeleteGraphic(numbers);
		DeleteGraphic(spellback);
		DeleteGraphic(spellnames);
		DeleteGraphic(spriteSatori);
		DeleteGraphic(spriteKoishi);
		DeleteGraphic(shield);
		DeleteGraphic(shots);
		DeleteGraphic(talk);
		DeleteGraphic(talk2);
		DeleteGraphic(stgframe);
		DeleteMusic(music);
		DeleteMusic(musicT);
		DeleteCommonData("Spell Active");
		DeleteCommonData("Spell Background Type");
		DeleteCommonData("X Satori");
		DeleteCommonData("Y Satori");
		DeleteCommonData("X Koishi");
		DeleteCommonData("Y Koishi");
		DeleteCommonData("Life Satori");
		DeleteCommonData("Life Koishi");
		DeleteCommonData("Dead Satori");
		DeleteCommonData("Dead Koishi");
		DeleteCommonData("Lower Life");
		DeleteCommonData("Life Master");
		DeleteCommonData("Life Master Max");
		DeleteCommonData("Life Type");
		DeleteCommonData("Life Type Current");
		DeleteCommonData("Ending");
		DeleteCommonData("Chosen Difficulty");
		DeleteCommonData("Difficulty");
	}
	@MainLoop {
		if(GetCommonDataDefaultEx("Config", "Background", true) && chosediff) { BGLogic; }
		if(GetCommonDataDefault("Spell Active", false) == true) {
			if(spellalpha < 89/90) { spellalpha+=1/90; } else { spellalpha = 1; }
		} else {
			spellalpha = 0;
		}
		if(GetCommonDataDefault("Get Spell Card Bonus!", -1) > 0) {
			GetSpellCardBonusDraw(GetCommonDataDefault("Get Spell Card Bonus!", -1));
			SetCommonData("Get Spell Card Bonus!", -1);
		} else if(GetCommonDataDefault("Get Spell Card Bonus!", -1) == 0) {
			BonusFailedDraw;
			SetCommonData("Get Spell Card Bonus!", -1);
		}
		controlbgspell1-=2; controlbgspell1%=512;
		controlbgspell2+=3/4; controlbgspell2%=360;
		controlbgspell3+=5/7; controlbgspell3%=360;
		controlbgspell4-=11/17; controlbgspell4%=360;
		controlbgspell5+=2/5; controlbgspell5%=360;
		yield;
	}
	task KomeijiStage {
		yield;
		ChooseDifficulty;
		while(!chosediff) { yield; }
		loop(120) { yield; }
		StageIntro;
		PlayMusic(musicT); MusicName(0);
		loop(210) { yield; }
		StartBossFight;
	}
	function WaitForDefeatAttack {
		while(GetEnemyNum > 0) { yield; }
		DeleteEnemyShotToItem(ALL);
	}
	task StartBossFight {
		// Start Boss Fight
			StartBossSystem(4);
			KomeijiEvent;
		// NS 01
			CreateEnemyFromFile(GCSD ~ "Atk_Non1.txt", -256, 0, 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Non1_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Non1_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
				WaitForDefeatAttack;
		// SP 01
			CreateEnemyFromFile(GCSD ~ "Atk_Sc1.txt", -256, 0, 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Sc1_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Sc1_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
				WaitForDefeatAttack;
				stars--;
		if(GetPlayerScriptName == "_PlayerA.txt") {
			// NS 02
				CreateEnemyFromFile(GCSD ~ "Atk_NonSolo.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonSato_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonSato_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
			// SP 02
				CreateEnemyFromFile(GCSD ~ "Atk_Sc2S.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc2S_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
					WaitForDefeatAttack;
					stars--;
			// NS 03
				CreateEnemyFromFile(GCSD ~ "Atk_NonSolo.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonKoi_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonKoi_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
			// SP 03
				CreateEnemyFromFile(GCSD ~ "Atk_Sc3K.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc3K_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
					stars--;
		} else {
			// NS 02
				CreateEnemyFromFile(GCSD ~ "Atk_NonSolo.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonKoi_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonKoi_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
			// SP 02
				CreateEnemyFromFile(GCSD ~ "Atk_Sc2K.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc2K_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
					stars--;
			// NS 03
				CreateEnemyFromFile(GCSD ~ "Atk_NonSolo.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonSato_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_NonSato_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
			// SP 03
				CreateEnemyFromFile(GCSD ~ "Atk_Sc3S.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc3S_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
					WaitForDefeatAttack;
					stars--;
		}
		// NS 04
			CreateEnemyFromFile(GCSD ~ "Atk_Non2.txt", -256, 0, 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Non2_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Non2_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
				WaitForDefeatAttack;
		if(GetPlayerLife >= 4 || true) {
			SetCommonData("Being Koishi", true);
				// SP 04
					CreateEnemyFromFile(GCSD ~ "Atk_Sc4K.txt", -256, 0, 0, 0, 0);
					CreateEnemyFromFile(GCSD ~ "Atk_Sc4K_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
					CreateEnemyFromFile(GCSD ~ "Atk_Sc4K_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
						WaitForDefeatAttack;
						stars--;
			SetCommonData("Being Koishi", false);
		} else {
			// SP 04
				CreateEnemyFromFile(GCSD ~ "Atk_Sc4S.txt", -256, 0, 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc4S_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
				CreateEnemyFromFile(GCSD ~ "Atk_Sc4S_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
					WaitForDefeatAttack;
					stars--;
		}
		// SP 05
			CreateEnemyFromFile(GCSD ~ "Atk_Sc5.txt", -256, 0, 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Sc5_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Atk_Sc5_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
				WaitForDefeatAttack;
				stars--;
		stars = 0;
		onBoss = false;
		KomeijiEvent2;
		CreateEnemyFromFile(GCSD ~ "Die_Master.txt", -256, 0, 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Die_Satori.txt", GetCommonData("X Satori"), GetCommonData("Y Satori"), 0, 0, 0);
			CreateEnemyFromFile(GCSD ~ "Die_Koishi.txt", GetCommonData("X Koishi"), GetCommonData("Y Koishi"), 0, 0, 0);
		WaitForDefeatAttack;
	}
	task KomeijiEvent { InitializeEvent(1, 2);
		SetCutinGraphic(0, 0, 1, 0);
		SetCutinGraphic(1, 0, 0, 1);
		SetCutinGraphic(1, 1, 0, 2);
		SetCharStatusPresent(0, 0, true);
		SetCharStatusTalking(0, 0, true);
		SetEventText(0, 3, 0, 256, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, false);
		SetCharStatusTalking(1, 1, true);
		SetEventStepEx(1);
		SetEventText(1, 1, 1, 96, 90);
		SetCharStatusPresent(1, 0, true);
		SetCharStatusPresent(1, 1, true);
		SetEventText(1, 0, 2, 224, 0);
		SetCutinGraphic(0, 0, 0, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 1, false);
		SetEventText(0, 0, 3, 288, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetEventText(1, 3, 4, 224, 0);
		SetCutinGraphic(0, 0, 2, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 0, false);
		SetCutinGraphic(1, 0, 1, 1);
		SetEventText(0, 3, 5, 240, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetEventText(1, 3, 6, 224, 0);
		SetCutinGraphic(1, 1, 2, 2);
		SetCharStatusTalking(1, 0, false);
		SetCharStatusTalking(1, 1, true);
		SetEventText(1, 0, 7, 256, 0);
		SetCutinGraphic(1, 1, 3, 2);
		SetEventText(1, 3, 8, 240, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 1, false);
		SetCutinGraphic(0, 0, 7, 0);
		SetEventText(0, 3, 9, 256, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetCutinGraphic(1, 0, 2, 1);
		SetEventText(1, 3, 10, 224, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 0, false);
		SetCutinGraphic(0, 0, 6, 0);
		SetEventText(0, 1, 11, 208, 0);
		SetEventStepEx(2);
		PlayMusic(music); MusicName(1);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetCutinGraphic(1, 0, 2, 1);
		SetEventText(1, 3, 12, 240, 0);
		SetEventText(1, 3, 13, 256, 0);
		SetCharStatusTalking(1, 0, false);
		SetCharStatusTalking(1, 1, true);
		SetCutinGraphic(1, 0, 2, 1);
		SetEventText(1, 3, 14, 272, 0);
		SetEventText(1, 3, 15, 240, 0);
		SetCharStatusPresent(0, 0, false);
		SetCharStatusPresent(1, 0, false);
		SetCharStatusPresent(1, 1, false);
		loop(45) { yield; }
	FinalizeEvent; }
	task KomeijiEvent2 { loop(45) { yield; } InitializeEvent(1, 2);
		SetCutinGraphic(0, 0, 0, 0);
		SetCutinGraphic(1, 0, 3, 1);
		SetCutinGraphic(1, 1, 4, 2);
		SetCharStatusPresent(0, 0, true);
		SetCharStatusPresent(1, 0, true);
		SetCharStatusPresent(1, 1, true);
		SetCharStatusTalking(1, 1, true);
		SetEventText(1, 3, 20, 384, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 1, false);
		SetCutinGraphic(0, 0, 4, 0);
		SetEventText(0, 3, 21, 336, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetEventText(1, 3, 22, 336, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 0, false);
		SetCutinGraphic(0, 0, 5, 0);
		SetEventText(0, 3, 23, 288, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetEventText(1, 3, 24, 288, 0);
		SetEventText(1, 0, 25, 368, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 0, false);
		SetCutinGraphic(0, 0, 7, 0);
		SetEventText(0, 0, 26, 400, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 1, true);
		SetEventText(1, 3, 27, 320, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 1, false);
		SetEventText(0, 3, 28, 308, 0);
		SetCharStatusTalking(0, 0, false);
		SetCharStatusTalking(1, 0, true);
		SetEventText(1, 3, 29, 192, 0);
		SetCharStatusTalking(1, 0, false);
		SetCharStatusTalking(1, 1, true);
		SetEventText(1, 0, 30, 416, 0);
		SetCharStatusTalking(0, 0, true);
		SetCharStatusTalking(1, 1, false);
		SetCutinGraphic(0, 0, 1, 0);
		SetEventText(0, 4, 31, 272, 0);
		SetCharStatusPresent(0, 0, false);
		SetCharStatusPresent(1, 0, false);
		SetCharStatusPresent(1, 1, false);
		loop(45) { yield; }
		FinalizeEvent;
		ForbidBomb(true);
		loop(60) { yield; }
		SetCommonData("Ending", true);
		FadeOutMusic(music, 12);
		FadeOutEnd;
	}
	task FadeOutEnd {
		let obj2 = Obj_Create(OBJ_EFFECT);
		ObjEffect_SetPrimitiveType(obj2, PRIMITIVE_TRIANGLEFAN);
		ObjEffect_SetLayer(obj2, 8);
		ObjEffect_SetTexture(obj2, numbers);
		ObjEffect_CreateVertex(obj2, 4);
		Obj_SetPosition(obj2, GetCenterX, GetCenterY/2);
			ObjEffect_SetVertexUV(obj2, 0, 0, 192);
			ObjEffect_SetVertexUV(obj2, 1, 256, 192);
			ObjEffect_SetVertexUV(obj2, 2, 256, 255);
			ObjEffect_SetVertexUV(obj2, 3, 0, 255);
			ObjEffect_SetVertexXY(obj2, 0, -128, -32);
			ObjEffect_SetVertexXY(obj2, 1, 128, -32);
			ObjEffect_SetVertexXY(obj2, 2, 128, 32);
			ObjEffect_SetVertexXY(obj2, 3, -128, 32);
		descent(i in 0..60) { ascent(j in 0..4) { ObjEffect_SetVertexColor(obj2, j, 255*cos(i*90/60), 255, 255, 255); } yield; }
		loop(60) { yield; }
		let obj = Obj_Create(OBJ_EFFECT);
		Obj_SetPosition(obj, 0, 0);
		ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN);
		ObjEffect_SetLayer(obj, 8);
		ObjEffect_SetTexture(obj, white);
		ObjEffect_CreateVertex(obj, 4);
			ObjEffect_SetVertexUV(obj, 0, 0, 0);
			ObjEffect_SetVertexUV(obj, 1, 64, 0);
			ObjEffect_SetVertexUV(obj, 2, 64, 64);
			ObjEffect_SetVertexUV(obj, 3, 0, 64);
			ObjEffect_SetVertexXY(obj, 0, 0, 0);
			ObjEffect_SetVertexXY(obj, 1, 640, 0);
			ObjEffect_SetVertexXY(obj, 2, 640, 480);
			ObjEffect_SetVertexXY(obj, 3, 0, 480);
		descent(i in 0..180) { ascent(j in 0..4) { ObjEffect_SetVertexColor(obj, j, 255*cos(i*90/180), 1, 1, 1); } yield; }
		Clear;
	}
}