#include "scenario_common.h" // Global variable int numBossDefeat = 0; int cutscenePlayed = 0; int AliciaID = -1; int NatashaID = -1; int BoneLegionID[3]; int bGameStart = 0; //int bBloodPillarSwitch = 0; //int SwitchID = -1; int AliciaAI = 0; int NatashaAI = 0; // 0: normal 1: going switch 2: going recover 3: going play piano 4: playing piano float MusicTime = 235.2; int bHeal; float BloodOrigin[3]; int Blood01ID = -1; int Blood02ID = -1; int OrganID = -1; float GStartTime, CurTime, MusicStartTime; float fTime; int bGotoPiano = 0; int bMusicPlaying = 0; float bFirstHeal = 1; // use secondary bUseSecondary = 1; // scene has echo bVoiceEcho = 1; // Partner Position SpawnPartnerX = 0; SpawnPartnerY = -200; SpawnPartnerZ = 50; // local variable float HP[2], MaxHP[2]; int i, ObjectID; // constant int BossAttackRange = 150; // -------- // Boss // -------- void BONELEGION_InitChara(int id) { // cw10 NPCW10_InitChara(id); SetCharaAttrib(id, CHARA_MAX_HP, 400*HandicapHP); // 生命上限 SetCharaAttrib(id, CHARA_HP, 400*HandicapHP); // 生命 SetCharaAttrib(id, CHARA_TEAM, 2); SetCharaWeapon(id, 52); } void BONELEGION_InitAI(int id) { AI_Captain(PlayerID, id); } void NATASHA_InitChara(int id) { CW05_InitChara(id); SetCharaAttrib(id, CHARA_MAX_HP, 2000*HandicapHP); SetCharaAttrib(id, CHARA_HP, 2000*HandicapHP); SetCharaAttrib(id, CHARA_TEAM, 2); SetCharaWeapon(id, 10); SetCharaDart(id, 1, 30); } void NATASHA_InitAI(int id) { AI_Boss(PlayerID, id); SetAIAttrib(id, AI_ATTACK_RATE, 90); SetAIAttrib(id, AI_ATTACK_RANGE, BossAttackRange); SetAIAttrib(id, AI_DEFENSE_RATE, 60); SetAIAttrib(id, AI_DEMON_RATE, 20); ClearAIAllBehavior(id); // set AI behavior SetAIBehavior(id, AI_STATE_SEARCH, AI_SEARCH_FOLLOW, 50); // id, type, num, rate SetAIBehavior(id, AI_STATE_SEARCH, AI_SEARCH_RANDOMRUN, 50); SetAIBehavior(id, AI_STATE_LOCK, AI_LOCK_NEAREST_TARGET, 100); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_DIRECT, 50); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_DASH_BACK, 50); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_DASH_FRONT, 50); SetAIBehavior(id, AI_STATE_ATTACK, AI_ATTACK_RANDOM, 20); SetAIBehavior(id, AI_STATE_ATTACK, AI_ATTACK_COMBO, 80); UpdateAIAttrib(id); } void ALICIA_InitChara(int id) { CW06_InitChara(id); SetCharaAttrib(id, CHARA_MAX_HP, 2000*HandicapHP); SetCharaAttrib(id, CHARA_HP, 2000*HandicapHP); SetCharaAttrib(id, CHARA_TEAM, 2); SetCharaWeapon(id, 12); SetCharaDart(id, 1, 30); } void ALICIA_InitAI(int id) { AI_Boss(PlayerID, id); SetAIAttrib(id, AI_ATTACK_RATE, 80); SetAIAttrib(id, AI_ATTACK_RANGE, BossAttackRange); SetAIAttrib(id, AI_DEFENSE_RATE, 80); SetAIAttrib(id, AI_DEMON_RATE, 20); ClearAIAllBehavior(id); // set AI behavior SetAIBehavior(id, AI_STATE_SEARCH, AI_SEARCH_FOLLOW, 50); // id, type, num, rate SetAIBehavior(id, AI_STATE_SEARCH, AI_SEARCH_RANDOMRUN, 50); SetAIBehavior(id, AI_STATE_LOCK, AI_LOCK_NEAREST_TARGET, 100); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_DIRECT, 50); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_MOVE_SIDE, 50); SetAIBehavior(id, AI_STATE_PREATTACK, AI_ATTACKMOVE_JUMP_SIDE, 50); SetAIBehavior(id, AI_STATE_ATTACK, AI_ATTACK_RANDOM, 20); SetAIBehavior(id, AI_STATE_ATTACK, AI_ATTACK_COMBO, 80); UpdateAIAttrib(id); } void RunBossAI() { /* if (AliciaAI == 0) { Print("sw id = ", SwitchID, "\n"); // ChangeBehavior(AliciaID, "AI_SEARCH_FOLLOW, SwitchID); AIPerform(AliciaID, AI_PERFORM_MOVETO, 20); AliciaAI = 1; } else if (IsReachPoint(AliciaID, 20)) { AIPerform(AliciaID, AI_PERFORM_FACETO, SwitchID); AIPerform(AliciaID, AI_PERFORM_UNLOCK); AIPerform(AliciaID, AI_PERFORM_ATTACK, "^Y"); // AIPerform(AliciaID, AI_PERFORM_NONE); AIPerform(AliciaID, AI_PERFORM_MOVETO, 0); } */ HP[0] = GetCharaAttrib(AliciaID, CHARA_HP); HP[1] = GetCharaAttrib(NatashaID, CHARA_HP); // check piano time if ( IsReachPoint(AliciaID, 40) && (AliciaAI != 4) ) { if ( (fTime >= 0) && (fTime < 10) ) { ChangeBehavior(AliciaID, AI_SEARCH_IDLE); // AIPerform(NatashaID, AI_PERFORM_MOVETO, 40); } else if ( (fTime >= 10) && (fTime < 30) ) { AIPerform(AliciaID, AI_PERFORM_NONE); AIPerform(AliciaID, AI_PERFORM_FACETO, OrganID); AIPerform(AliciaID, AI_PERFORM_POSE, 163, 30-fTime); AliciaAI = 4; } } if ( IsReachPoint(NatashaID, 40) && (NatashaAI != 4) ) { if ( (fTime >= 0) && (fTime < 10) ) { // Print("idle\n"); ChangeBehavior(NatashaID, AI_SEARCH_IDLE); // AIPerform(NatashaID, AI_PERFORM_MOVETO, 40); } else if ( (fTime >= 10) && (fTime < 30) ) { AIPerform(NatashaID, AI_PERFORM_NONE); AIPerform(NatashaID, AI_PERFORM_FACETO, OrganID); AIPerform(NatashaID, AI_PERFORM_POSE, 163, 30-fTime); NatashaAI = 4; } } if ( (fTime <= 28) && (bGotoPiano == 0) ) { MusicStartTime = GetMusicPlayTime() - GStartTime; bGotoPiano = 1; if (HP[0] > HP[1]) { Print("Alicia going! fTime = ", fTime, ", MusicTime = ", GetMusicPlayTime(), "\n"); SetAIAttrib(AliciaID, AI_LOOK_RANGE, 0); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, 0); AIPerform(AliciaID, AI_PERFORM_UNLOCK); AIPerform(AliciaID, AI_PERFORM_MOVETOPOINT, 40); AliciaAI = 3; } else { Print("Natasha going! fTime = ", fTime, ", MusicTime = ", GetMusicPlayTime(), "\n"); SetAIAttrib(NatashaID, AI_LOOK_RANGE, 0); SetAIAttrib(NatashaID, AI_ATTACK_RANGE, 0); AIPerform(NatashaID, AI_PERFORM_UNLOCK); AIPerform(NatashaID, AI_PERFORM_MOVETOPOINT, 40); NatashaAI = 3; } } if (AliciaAI < 2) { /* if (bBloodPillarSwitch == 0) { // check boss blood if ( HP[0] < (MaxHP[0]/2) ) { if (IsReachPoint(AliciaID, 20) ) { // face switch AIPerform(AliciaID, AI_PERFORM_NONE); AIPerform(AliciaID, AI_PERFORM_FACETO, SwitchID); AIPerform(AliciaID, AI_PERFORM_ATTACK, "^Y"); AIPerform(AliciaID, AI_PERFORM_MOVETOPOINT, 0); // SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); // SetAIAttrib(AliciaID, AI_ATTACK_RANGE, 250); AliciaAI = 2; } if ( AliciaAI == 0 ) { SetAIAttrib(AliciaID, AI_LOOK_RANGE, 0); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, 0); // ChangeBehavior(AliciaID, AI_SEARCH_FOLLOW, SwitchID); AIPerform(AliciaID, AI_PERFORM_UNLOCK); AIPerform(AliciaID, AI_PERFORM_MOVETOPOINT, 20); AliciaAI = 1; } } } else */ { // check boss blood if ( HP[0] < (MaxHP[0]/2) ) { // run to blood pillar SetAIAttrib(AliciaID, AI_LOOK_RANGE, 0); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, 0); AIPerform(AliciaID, AI_PERFORM_UNLOCK); AIPerform(AliciaID, AI_PERFORM_MOVETOPOINT, 0); AliciaAI = 2; if (bFirstHeal) { BeginCutscene("shortcut_drinkbloodal"); bFirstHeal = 0; } } } } else if (AliciaAI == 2) { if (HP[0] >= (MaxHP[0]/2) ) { SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); ChangeBehavior(AliciaID, AI_SEARCH_FOLLOW, PlayerID); AliciaAI = 0; } else if ( IsReachPoint(AliciaID, 0) ) { ChangeBehavior(AliciaID, AI_SEARCH_IDLE); } } if (NatashaAI < 2) { /* if (bBloodPillarSwitch == 0) { // check boss blood if ( HP[1] < (MaxHP[1]/2) ) { if (IsReachPoint(NatashaID, 20) ) { AIPerform(AliciaID, AI_PERFORM_NONE); AIPerform(NatashaID, AI_PERFORM_FACETO, SwitchID); AIPerform(NatashaID, AI_PERFORM_ATTACK, "^Y"); AIPerform(NatashaID, AI_PERFORM_MOVETOPOINT, 0); // SetAIAttrib(NatashaID, AI_LOOK_RANGE, 300); // SetAIAttrib(NatashaID, AI_ATTACK_RANGE, 250); NatashaAI = 2; } if ( NatashaAI == 0 ) { SetAIAttrib(NatashaID, AI_LOOK_RANGE, 0); SetAIAttrib(NatashaID, AI_ATTACK_RANGE, 0); // ChangeBehavior(NatashaID, AI_SEARCH_FOLLOW, SwitchID); AIPerform(NatashaID, AI_PERFORM_UNLOCK); AIPerform(NatashaID, AI_PERFORM_MOVETOPOINT, 20); NatashaAI = 1; } } } else */ { if ( HP[1] < (MaxHP[1]/2) ) { // run to blood pillar AIPerform(NatashaID, AI_PERFORM_UNLOCK); AIPerform(NatashaID, AI_PERFORM_MOVETOPOINT, 0); NatashaAI = 2; if (bFirstHeal) { BeginCutscene("shortcut_drinkbloodna"); bFirstHeal = 0; } } } } else if (NatashaAI == 2) { if (HP[1] >= (MaxHP[1]/2) ) { SetAIAttrib(NatashaID, AI_LOOK_RANGE, 300); SetAIAttrib(NatashaID, AI_ATTACK_RANGE, BossAttackRange); ChangeBehavior(NatashaID, AI_SEARCH_FOLLOW, PlayerID); NatashaAI = 0; } else if ( IsReachPoint(NatashaID, 0) ) { ChangeBehavior(NatashaID, AI_SEARCH_IDLE); } } } void SHORTCUT_DRINKBLOODAL_OnEnd() { TeleportChara(AliciaID, 0, 0, 50); } void SHORTCUT_DRINKBLOODNA_OnEnd() { TeleportChara(NatashaID, 0, 0, 50); } // ------- // Game // ------- void OnCache() { LoadScene("sw05"); // CacheLevelModel(""); } void OnHostGame() { SetGameMaxTime(-1); InitScenario(); // Spawn Boss AliciaID = SpawnChara("alicia", 461.09, -7.31, 50); NatashaID = SpawnChara("natasha", -261, -32, 50); // Spawn Bone Legion for (i = 0 ; i < 3 ; i++) { ObjectID = FindSceneItem(NumToStr("BONELEGION_%02d", i)); GetSceneItemPos(ObjectID, x, y, z); BoneLegionID[i] = SpawnChara("bonelegion", x, y, z); if ( (i % 3) == 0 ) SetCharaWeapon(BoneLegionID[i], 62); // SetCharaAttrib(BoneLegionID[i], CHARA_HP, 0); } /* SetSceneObjectSwitch("SwitchLight01", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight02", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight03", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight04", "PRESENT", 0); SwitchID = FindItem("SWITCH_01"); */ OrganID = FindItem("ORGAN"); MaxHP[0] = GetCharaAttrib(AliciaID, CHARA_MAX_HP); MaxHP[1] = GetCharaAttrib(NatashaID, CHARA_MAX_HP); var_aiLockCountLimit = 5; // mission SetMissionObjectiveText(0, MOBJ_SW05_1); var_uiGameOverVoice2 = NumToStr("al_d%d", rand()%2+1); Print("cutscene25\n"); BeginCutscene("cutscene25"); bGameStart = 1; } void CUTSCENE25_OnEnd() { PlayMusic("s15_summoning_boss"); SetAudioVariable(0, 0); } void OnCharaDead(int id, int killer) { Print("Chara ", id, " is killed by ", killer, "\n"); if (id == PlayerID) GameOver(GAMEOVER_LOSE); if (id == PartnerID) PartnerDead(); if (id == AliciaID) { KillScore(1, 2000); numBossDefeat++; // run cutscene 6-1 Print("shorcut6-1\n"); BeginCutscene("shortcut6_1", "BossDead"); var_uiGameOverVoice2 = NumToStr("na_d%d", rand()%2+1); } else if (id == NatashaID) { KillScore(1, 2000); numBossDefeat++; // run cutscene 6-2 Print("shorcut6-2\n"); BeginCutscene("shortcut6_2", "BossDead"); // change Alicia weapon to iron phoenix if (!IsCharaDead(AliciaID)) SetCharaWeapon(AliciaID, 10); } for (i = 0 ; i < 3 ; i++) { if (id == BoneLegionID[i]) { KillScore(0, 525); break; } } // CharaReborn(id); } void BOSSDEAD_OnEnd() { // check if all boss are defeated if (numBossDefeat == 2) { SetMissionObjectiveSwitch(0, 0); PlayAICutsceneCB("cutscene26", "GameComplete"); } } void OnTimeOver() { Print("TimeOver\n"); GameOver(GAMEOVER_LOSE); } void OnUpdate(float t) { CommonUpdate(t); if (bGameStart == 1) { Print("StartTime = ", GetGameTime(), ", Real = ", GetRealTime(), "\n"); bGameStart = 0; GStartTime = -72.5; SetAudioVariable(0, 5500); Print("Set Variable 5500\n"); AIPerform(AliciaID, AI_PERFORM_NONE); AIPerform(AliciaID, AI_PERFORM_FACETO, OrganID); AIPerform(AliciaID, AI_PERFORM_POSE, 163, 10); SetAIAttrib(AliciaID, AI_LOOK_RANGE, 0); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, 0); CharaSickSlow(PlayerID, 10); AliciaAI = 4; MusicStartTime = -8 - GStartTime; bGotoPiano = 1; bMusicPlaying = 1; } CurTime = GetMusicPlayTime() - GStartTime; fTime = fmod(CurTime, MusicTime); // Check Boss AI RunBossAI(); // Stop Piano Music if ( bGotoPiano && ( (CurTime - MusicStartTime) > 28 ) ) { bGotoPiano = 0; if (AliciaAI >= 3) { SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); ChangeBehavior(AliciaID, AI_SEARCH_FOLLOW, PlayerID); AliciaAI = 0; } if (NatashaAI >= 3) { SetAIAttrib(NatashaID, AI_LOOK_RANGE, 300); SetAIAttrib(NatashaID, AI_ATTACK_RANGE, BossAttackRange); ChangeBehavior(NatashaID, AI_SEARCH_FOLLOW, PlayerID); NatashaAI = 0; } } // check playing status if (GetCharaBodyPose(NatashaID) == 163) { if (!bMusicPlaying) { bMusicPlaying = 1; SetAudioVariable(0, 5500); Print("Set Variable 5500\n"); } CharaSickPoison(PlayerID); CharaSickPoison(PartnerID); } else if (GetCharaBodyPose(NatashaID) == 163) { if (!bMusicPlaying) { bMusicPlaying = 1; SetAudioVariable(0, 5500); Print("Set Variable 5500\n"); } CharaSickSlow(PlayerID); CharaSickSlow(PartnerID); } else { if (bMusicPlaying) { bMusicPlaying = 0; SetAudioVariable(0, 3000); Print("Set Variable 3000\n"); } } if (bHeal) { // reborn Bone Legion for(i = 0 ; i < 3 ; i++) { if(IsCharaDead(BoneLegionID[i])) { ObjectID = FindSceneItem(NumToStr("BONELEGION_%02d", i)); GetSceneItemPos(ObjectID, x, y, z); CharaReborn(BoneLegionID[i], 0); TeleportChara(BoneLegionID[i], x, y, z); } } } if (bHeal & 1) { Print("Alicia Heal! ", t, "\n"); HP[0] = HP[0] + 100*t; if (HP[0] >= MaxHP[0]) HP[0] = MaxHP[0]; SetCharaAttrib(AliciaID, CHARA_HP, HP[0]); } if (bHeal & 2) { Print("Natasha Heal! ", t, "\n"); HP[1] = HP[1] + 100*t; if (HP[1] >= MaxHP[1]) HP[1] = MaxHP[1]; SetCharaAttrib(NatashaID, CHARA_HP, HP[1]); } bHeal = 0; } /* // --------- // switch // --------- void SWITCH_InitItem(int id) { SetItemAttrib(id, ITEM_MODEL, "sw05switch"); SetItemAttrib(id, ITEM_PHYSICS, ITEM_PHYSICS_NONE); SetItemAttrib(id, ITEM_LIFTABLE, 0); SetItemAttrib(id, ITEM_PICKABLE, 0); ShowEntity(id, 0); } void SWITCH_OnAttack(int id, int CharaId, int damage) { Print("Switch ", id, " be attacked\n"); if ( bBloodPillarSwitch ) { bBloodPillarSwitch = 0; SetSceneObjectSwitch("SwitchLight01", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight02", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight03", "PRESENT", 0); SetSceneObjectSwitch("SwitchLight04", "PRESENT", 0); // hide blood and return origin pos SetItemAttrib(Blood01ID, ITEM_PHYSICS, ITEM_PHYSICS_NONE); ShowEntity(Blood01ID, 0); SetEntityPos(Blood01ID, BloodOrigin[0], BloodOrigin[1], 150); ShowEntity(Blood02ID, 0); } else { bBloodPillarSwitch = 1; SetSceneObjectSwitch("SwitchLight01", "PRESENT", 1); SetSceneObjectSwitch("SwitchLight02", "PRESENT", 1); SetSceneObjectSwitch("SwitchLight03", "PRESENT", 1); SetSceneObjectSwitch("SwitchLight04", "PRESENT", 1); // show blood SetItemAttrib(Blood01ID, ITEM_PHYSICS, ITEM_PHYSICS_MACHINE); SetItemAttrib(Blood01ID, ITEM_NEXTPOINT, 1); ShowEntity(Blood01ID, 1); ShowEntity(Blood02ID, 1); } } */ // -------------- // Blood Pillar // -------------- void BLOOD01_InitItem(int id) { Blood01ID = id; // GetEntityPos(id, BloodOrigin[0], BloodOrigin[1], BloodOrigin[2]); SetItemAttrib(id, ITEM_MODEL, "sw05blood01", 1); SetItemAttrib(id, ITEM_PHYSICS, ITEM_PHYSICS_NONE); SetItemAttrib(id, ITEM_LIFTABLE, 0); SetItemAttrib(id, ITEM_PICKABLE, 0); // SetItemAttrib(id, ITEM_MOVEPOINT, 2, BloodOrigin[0], BloodOrigin[1], 150, BloodOrigin[0], BloodOrigin[1], 77.938); // SetItemAttrib(id, ITEM_WAITTIME, 0); // SetItemAttrib(id, ITEM_MOVETYPE, 0); // SetItemAttrib(id, ITEM_MOVESPEED, 200); // SetItemAttrib(id, ITEM_NEXTPOINT, 1); // ShowEntity(id, 0); } void BLOOD01_OnTouch(int id, int charaId) { if (IsCharaDead(charaId)) return; // Print(id, " be triggered by ", charaId, "\n"); // if (!bBloodPillarSwitch) // return; if (charaId == AliciaID) { bHeal = bHeal | 1; SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); } if (charaId == NatashaID) { bHeal = bHeal | 2; SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); } } void BLOOD02_InitItem(int id) { Blood02ID = id; SetItemAttrib(id, ITEM_MODEL, "sw05blood02", 1); SetItemAttrib(id, ITEM_PHYSICS, ITEM_PHYSICS_NONE); SetItemAttrib(id, ITEM_LIFTABLE, 0); SetItemAttrib(id, ITEM_PICKABLE, 0); // ShowEntity(id, 0); } void BLOOD02_OnTouch(int id, int charaId) { if (IsCharaDead(charaId)) return; // if (!bBloodPillarSwitch) // return; if (charaId == AliciaID) { bHeal = bHeal | 1; SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); } if (charaId == NatashaID) { bHeal = bHeal | 2; SetAIAttrib(AliciaID, AI_LOOK_RANGE, 300); SetAIAttrib(AliciaID, AI_ATTACK_RANGE, BossAttackRange); } }