//:://///////////////////////////////////////////// //:: Custom User Defined Event //:: FileName hx_ud_meph //:: Copyright (c) 2001 Bioware Corp. //::////////////////////////////////////////////// /* This will handle the custom fighting for Meph. */ //::////////////////////////////////////////////// //:: Created By: Brad Prince //:: Created On: Sept 10, 2003 //::////////////////////////////////////////////// #include "hx_inc_meph" #include "x2_inc_toollib" #include "x2_inc_cutscene" // Damage from Meph's gaze. void DoRadiusDamage(location lLoc); // Clear effects on PC and associates, and remove effects from Meph. void ClearMephsEffects(object oObject); // Jump PC and associates. void AllJumpToLocation(object oObject, location lLoc); void main() { int nUser = GetUserDefinedEventNumber(); // The heartbeat will check if the PC is trying to hide from Meph // on the grapple platforms. If so, he will summon them to him. if(nUser == 1001) //HEARTBEAT { int iReady = GetMephReady(); object oPC = GetFirstPC(); int iGrapple = GetPCAtGrapple(oPC); if(GetLocalInt(OBJECT_SELF, "bSurrender") == TRUE) return; // Don't do anything in a cutscene. int iCut = CutGetActiveCutsceneForObject(oPC); if(iCut < 1) { // Only do the heartbeat if Meph isn't ready for takeoff. if(iReady != 1 && (iGrapple == 1 || GetDistanceToObject(oPC) >= 10.0)) { vector vPos = GetPosition(OBJECT_SELF); vector vNew = Vector(vPos.x + 3.0, vPos.y, vPos.z); location lLoc = Location(GetArea(OBJECT_SELF), vNew, GetFacing(oPC)); // He will either summon you, or use his gaze. if(Random(100) > 40) { ClearAllActions(TRUE); ActionCastFakeSpellAtLocation(SPELL_WEIRD, lLoc); DelayCommand(2.2, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_LOS_EVIL_20), lLoc)); //DelayCommand(3.0, TLVFXPillar(VFX_FNF_IMPLOSION, GetLocation(oPC), 4, 0.1, 4.0, -1.0)); DelayCommand(2.2, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_LOS_EVIL_20), GetLocation(oPC))); DelayCommand(2.3, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HARM), oPC)); DelayCommand(3.0, AllJumpToLocation(oPC, lLoc)); DelayCommand(3.4, ActionAttack(oPC)); } else { location lLoc = GetLocation(oPC); ClearAllActions(TRUE); SetFacingPoint(GetPosition(oPC)); DelayCommand(0.8, PlayAnimation(ANIMATION_FIREFORGET_TAUNT)); DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOW_ORANGE), OBJECT_SELF, 2.5)); DelayCommand(2.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(481), lLoc)); DelayCommand(2.5, DoRadiusDamage(lLoc)); } } } } else if(nUser == 1002) // PERCEIVE { } else if(nUser == 1003) // END OF COMBAT { if(GetLocalInt(OBJECT_SELF, "bSurrender") == TRUE) return; // Don't do shouts in a cutscene. int iCut = CutGetActiveCutsceneForObject(GetFirstPC()); if(iCut < 1) { if(Random(100) < 35) { SpeakOneLinerConversation("hx_mephcmbt_conv"); } } } else if(nUser == 1004) // ON DIALOGUE { } else if(nUser == 1005) // ATTACKED { } else if(nUser == 1006) // DAMAGED { object oPC = GetFirstPC(); int iMax = GetMaxHitPoints(); int iHPs = GetCurrentHitPoints(); int iState = GetMephCount(); object oDestroy = GetNearestObjectByTag("hx_meph_building", oPC); int iReady = GetLocalInt(OBJECT_SELF, "HX_READY_4_DAMAGE"); // Variable indicating that he's been commanded by his True Name to fight. int iCommand = GetLocalInt(GetModule(), "bMephCommandedToFight"); if(iReady != 1) { if(iState == 0 && iHPs < iMax - 100) { SetLocalInt(OBJECT_SELF, "HX_READY_4_DAMAGE", 1); // Stop the heartbeat. SetMephReady(); // Advance the fight state. AssignCommand(GetArea(OBJECT_SELF), DelayCommand(5.0, SetMephCount())); // Set the damage taken so far. SetMephDamage(iMax - iHPs); // Fly away. AssignCommand(GetArea(OBJECT_SELF), DelayCommand(2.0, SignalEvent(oDestroy, EventUserDefined(5555)))); ClearAllActions(TRUE); AssignCommand(oPC, ClearAllActions(TRUE)); PlaySound("fs_flapfeather"); // Removing all effects effect eEff = GetFirstEffect(OBJECT_SELF); while(GetIsEffectValid(eEff)) { RemoveEffect(OBJECT_SELF, eEff); eEff = GetNextEffect(OBJECT_SELF); } DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDisappear(), OBJECT_SELF)); DelayCommand(0.2, NightToDay(GetFirstPC(), 2.0)); } else if(iState == 1 && iHPs < iMax/2) { SetLocalInt(OBJECT_SELF, "HX_READY_4_DAMAGE", 1); // Stop the heartbeat. SetMephReady(); // Advance the fight state. AssignCommand(GetArea(OBJECT_SELF), DelayCommand(5.0, SetMephCount())); // Set the damage taken so far. SetMephDamage(iMax - iHPs); // Fly away. AssignCommand(GetArea(OBJECT_SELF), DelayCommand(2.0, SignalEvent(oDestroy, EventUserDefined(4444)))); ClearAllActions(TRUE); AssignCommand(oPC, ClearAllActions(TRUE)); PlaySound("fs_flapfeather"); // Removing all effects effect eEff = GetFirstEffect(OBJECT_SELF); while(GetIsEffectValid(eEff)) { RemoveEffect(OBJECT_SELF, eEff); eEff = GetNextEffect(OBJECT_SELF); } DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDisappear(), OBJECT_SELF)); DelayCommand(0.2, NightToDay(GetFirstPC(), 2.0)); } else if(iState == 2 && iCommand == TRUE && iHPs < iMax/8) { SetLocalInt(OBJECT_SELF, "HX_READY_4_DAMAGE", 1); object oLava = GetNearestObjectByTag("hx_meph_lastlava"); // Almost dead. As a last ditch effort, summon lava. ClearAllActions(TRUE); //AssignCommand(oPC, ClearAllActions(TRUE)); ClearMephsEffects(oPC); ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), OBJECT_SELF); PlayAnimation(ANIMATION_FIREFORGET_TAUNT); DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOW_ORANGE), OBJECT_SELF, 2.5)); SignalEvent(oLava, EventUserDefined(4444)); DelayCommand(4.0, ActionAttack(oPC)); DelayCommand(5.0, SetImmortal(OBJECT_SELF, FALSE)); } else if(iState == 2 && iHPs < iMax/8) { SetLocalInt(OBJECT_SELF, "HX_READY_4_DAMAGE", 1); object oLava = GetNearestObjectByTag("hx_meph_lastlava"); // Set surrender state. SetLocalInt(OBJECT_SELF, "bSurrender", TRUE); // Almost dead. ClearAllActions(TRUE); //AssignCommand(oPC, ClearAllActions(TRUE)); ClearMephsEffects(oPC); SurrenderToEnemies(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), OBJECT_SELF, 6.0); DelayCommand(0.1, ClearAllActions(TRUE)); MusicBackgroundStop(GetArea(OBJECT_SELF)); DelayCommand(0.2, NightToDay(GetFirstPC(), 1.0)); DelayCommand(1.3, SpeakOneLinerConversation("h9_mephistophele")); } } } else if(nUser == 1007) // DEATH { object oSound = GetNearestObjectByTag("hx_lava_sound"); location lLoc = GetLocation(GetObjectByTag("hx_final_end_movie_wp")); // Clean up the lava after he dies. SoundObjectStop(oSound); MusicBackgroundStop(GetArea(OBJECT_SELF)); // bk - nov 11 2003 commenting this out because it seems // to break cutscene in the event that M dies quickly //AssignCommand(GetFirstPC(), ClearAllActions(TRUE)); //AssignCommand(GetFirstPC(), ActionJumpToLocation(lLoc)); SignalEvent(GetArea(OBJECT_SELF), EventUserDefined(7777)); } else if(nUser == 1008) // DISTURBED { } } // Damage from Meph's gaze. void DoRadiusDamage(location lLoc) { object oCreature = GetFirstObjectInShape(SHAPE_CUBE, 7.0, lLoc, TRUE, OBJECT_TYPE_CREATURE); int iDamage; object oSound = GetNearestObjectByTag("hx_crystal_fire_explode", OBJECT_SELF); SoundObjectPlay(oSound); while(GetIsObjectValid(oCreature)) { iDamage = Random(60) + 25; ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(iDamage, DAMAGE_TYPE_MAGICAL), oCreature); oCreature = GetNextObjectInShape(SHAPE_CUBE, 7.0, lLoc, TRUE, OBJECT_TYPE_CREATURE); } } // Clear effects on PC and associates, and remove effects from Meph. void ClearMephsEffects(object oObject) { object oHench1 = GetHenchman(oObject, 1); object oHench2 = GetHenchman(oObject, 2); object oHench3 = GetHenchman(oObject, 3); object oAssoc1 = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oObject); object oAssoc2 = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oObject); object oAssoc3 = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oObject); object oAssoc4 = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oObject); effect eEffect = GetFirstEffect(OBJECT_SELF); while(GetIsEffectValid(eEffect)) { RemoveEffect(OBJECT_SELF, eEffect); eEffect = GetNextEffect(OBJECT_SELF); } AssignCommand(oObject, ClearAllActions(TRUE)); if(GetIsObjectValid(oHench1)) { AssignCommand(oHench1, ClearAllActions(TRUE)); } if(GetIsObjectValid(oHench2)) { AssignCommand(oHench2, ClearAllActions(TRUE)); } if(GetIsObjectValid(oHench3)) { AssignCommand(oHench3, ClearAllActions(TRUE)); } if(GetIsObjectValid(oAssoc1)) { AssignCommand(oAssoc1, ClearAllActions(TRUE)); } if(GetIsObjectValid(oAssoc2)) { AssignCommand(oAssoc2, ClearAllActions(TRUE)); } if(GetIsObjectValid(oAssoc3)) { AssignCommand(oAssoc3, ClearAllActions(TRUE)); } if(GetIsObjectValid(oAssoc4)) { AssignCommand(oAssoc4, ClearAllActions(TRUE)); } } // Jump PC and associates. void AllJumpToLocation(object oObject, location lLoc) { object oHench1 = GetHenchman(oObject, 1); object oHench2 = GetHenchman(oObject, 2); object oHench3 = GetHenchman(oObject, 3); object oAssoc1 = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oObject); object oAssoc2 = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oObject); object oAssoc3 = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oObject); object oAssoc4 = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oObject); AssignCommand(oObject, ClearAllActions(TRUE)); AssignCommand(oObject, ActionJumpToLocation(lLoc)); if(GetIsObjectValid(oHench1)) { AssignCommand(oHench1, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oHench1, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oHench2)) { AssignCommand(oHench2, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oHench2, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oHench3)) { AssignCommand(oHench3, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oHench3, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oAssoc1)) { AssignCommand(oAssoc1, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oAssoc1, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oAssoc2)) { AssignCommand(oAssoc2, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oAssoc2, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oAssoc3)) { AssignCommand(oAssoc3, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oAssoc3, ActionJumpToLocation(lLoc))); } if(GetIsObjectValid(oAssoc4)) { AssignCommand(oAssoc4, ClearAllActions(TRUE)); DelayCommand(0.2, AssignCommand(oAssoc4, ActionJumpToLocation(lLoc))); } }