//============================================================================== /* A Paragon of Her Kind -> Broodmother Include Script */ //------------------------------------------------------------------------------ // Created By: joshua // Created On: February 19, 2009 //============================================================================== //#include"utility_h" //#include"events_h" //#include"cai_h" //#include"orz_constants_h" //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ //moved public const int EngineConstants.BROODMOTHER_EVENT_STOP_WAITING = EngineConstants.EVENT_TYPE_CUSTOM_EVENT_01; //moved public const int EngineConstants.BROODMOTHER_EVENT_TENTACLE_SURFACE = EngineConstants.EVENT_TYPE_CUSTOM_EVENT_02; //moved public const int EngineConstants.BROODMOTHER_EVENT_TENTACLE_RESET = EngineConstants.EVENT_TYPE_CUSTOM_EVENT_03; //moved public const int EngineConstants.BROODMOTHER_CAI_REINFORCEMENTS_FIRST_WAVE = 1000; //moved public const int EngineConstants.BROODMOTHER_CAI_REINFORCEMENTS_FIRST_WAVE_2 = 1001; //moved public const int EngineConstants.BROODMOTHER_CAI_REINFORCEMENTS_SECOND_WAVE = 1010; //moved public const int EngineConstants.BROODMOTHER_CAI_REINFORCEMENTS_SECOND_WAVE_2 = 1011; //moved public const int EngineConstants.BROODMOTHER_CAI_START = 1020; //moved public const int EngineConstants.BROODMOTHER_CAI_WAITING = 1030; //moved public const int EngineConstants.BROODMOTHER_CAI_TENTACLE_BURROW = 1040; //moved public const int EngineConstants.BROODMOTHER_CAI_TENTACLE_SURFACE = 1041; //moved public const float EngineConstants.BROODMOTHER_WAVE_1_HPP = 0.66f; //moved public const float EngineConstants.BROODMOTHER_WAVE_2_HPP = 0.33f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_MIN_ATTACK_DIST = 1.9f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_MIN_NEW_TARGET_DIST = 2.5f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_WAVE_RESET_DELAY = 30.0f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_WAVE_RESET_DELAY_OFFSET = 1.0f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_BURROW_DELAY = 2.5f; //moved public const float EngineConstants.BROODMOTHER_TENTACLE_BURROW_RESET_DELAY = 7.5f; //moved public const int EngineConstants.BROODMOTHER_TENTACLE_NUM_TENTACLES = 4; //moved public const string EngineConstants.BROODMOTHER_TENTACLE_WP = "wp_broodmother_tentacle"; //------------------------------------------------------------------------------ // Function Implementation //------------------------------------------------------------------------------ public int ORZ_Broodmother_Tentacle_IsEventValid(xEvent ev, GameObject oTentacle = null) { if (oTentacle == null) oTentacle = gameObject; GameObject oBroodmother = UT_GetNearestObjectByTag(oTentacle, EngineConstants.ORZ_CR_BROODMOTHER); if (GetEventIntegerRef(ref ev, 0) == GetLocalInt(oBroodmother, EngineConstants.CREATURE_COUNTER_1)) return EngineConstants.TRUE; return EngineConstants.FALSE; }
public static void Broadcast(int eventid, params object[] argv) { xEvent de = null; m_EventDic.TryGetValue(eventid, out de); if (de != null) { de(argv); } }
public static void UnRegEvent(int id, xEvent ac1) { if (m_EventDic.ContainsKey(id)) { m_EventDic[id] -= ac1; if (m_EventDic[id] == null) { m_EventDic.Remove(id); } } }
public static void RegEvent(int id, xEvent ac1) { if (m_EventDic.ContainsKey(id)) { m_EventDic[id] += ac1; } else { m_EventDic[id] = ac1; } }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_POPUP_RESULT event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandlePopupResult(xEvent ev) { GameObject oOwner = GetEventObjectRef(ref ev, 0); // owner of popup int nPopupID = GetEventIntegerRef(ref ev, 0); // popup ID (index into popup.xls) int nButton = GetEventIntegerRef(ref ev, 1); // button result (1 - 4) switch (nPopupID) { case 1: // Placeable area transition { if (nButton == 1) Placeable_DoAreaTransition(oOwner); break; } default: Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandlePopupResult()", "*** Unhandled popup ID: " + ToString(nPopupID)); break; } }
// ----------------------------------------------------------------------------- // @brief: Post resurrection event. Trigger soundset on player, add injury and // approval penalties // @author: Georg // ----------------------------------------------------------------------------- public int HandleEvent_Resurrection(GameObject oCreature, xEvent ev) { int bApplyInjury = engine.GetEventIntegerRef(ref ev, 0); if (bApplyInjury != EngineConstants.FALSE) { engine.PlaySoundSet(oCreature, EngineConstants.SS_EXPLORE_HEAL_ME); engine.Injury_DetermineInjury(oCreature); } // redo itemset bonuses engine.ItemSet_Update(oCreature); // CUT! //int nFollower = engine.Approval_GetFollowerIndex(gameObject); //if(nFollower != -1) // engine.Approval_ChangeApproval(nFollower, APPROVAL_DEATH_PENALTY); return EngineConstants.TRUE; }
public void HandleEvent(xEvent ev) { //xEvent ev = engine.GetCurrentEvent(); int nEventType = engine.GetEventTypeRef(ref ev); string sDebug; #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Received xEvent " + engine.ToString(nEventType), gameObject); #endif switch (nEventType) { // placeables only case EngineConstants.EVENT_TYPE_SPAWN: #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_LOOT, engine.GetCurrentScriptName(), "Generating Treasure - SPAWN", gameObject); #endif if (engine.GetPlaceableBaseType(gameObject) != EngineConstants.PLACEABLE_TYPE_BAG) { engine.TreasureGenerate(gameObject); } break; // creatures only case EngineConstants.EVENT_TYPE_DYING: if (engine.IsSummoned(gameObject) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_LOOT, engine.GetCurrentScriptName(), "Generating Treasure - DYING", gameObject); #endif engine.TreasureGenerate(gameObject); } break; } }
public override int StartingConditional(xEvent eParms) { //xEvent eParms = engine.GetCurrentEvent(); // Contains all input parameters int nType = engine.GetEventTypeRef(ref eParms); // GET or SET call string strPlot = engine.GetEventStringRef(ref eParms, 0); // Plot GUID int nFlag = engine.GetEventIntegerRef(ref eParms, 1); // The bit flag # being affected GameObject oParty = engine.GetEventCreatorRef(ref eParms); // The owner of the plot table for this script GameObject oConversationOwner = engine.GetEventObjectRef(ref eParms, 0); // Owner on the conversation, if any int nPlotType = engine.GetEventIntegerRef(ref eParms, 5); int bIsTutorial = engine.GetM2DAInt(EngineConstants.TABLE_PLOT_TYPES, "IsTutorial", nPlotType); int bIsCodex = engine.GetM2DAInt(EngineConstants.TABLE_PLOT_TYPES, "IsCodex", nPlotType); int nResult = EngineConstants.FALSE; // used to return value for DEFINED GET events GameObject oPC = engine.GetHero(); engine.plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info if (nType == EngineConstants.EVENT_TYPE_SET_PLOT) // actions -> normal flags only { int nValue = engine.GetEventIntegerRef(ref eParms, 2); // On SET call, the value about to be written (on a normal SET that should be '1', and on a 'clear' it should be '0') int nOldValue = engine.GetEventIntegerRef(ref eParms, 3); // On SET call, the current flag value (can be either 1 or 0 regardless if it's a set or clear event) // IMPORTANT: The flag value on a SET xEvent is set only AFTER this script finishes running! /*switch (nFlag) { }*/ } else // EngineConstants.EVENT_TYPE_GET_PLOT -> defined conditions only { /*switch (nFlag) { }*/ } engine.plot_OutputDefinedFlag(eParms, nResult); return nResult; }
public void HandleEvent(xEvent ev) { //xEvent ev = engine.GetCurrentEvent(); int nEventType = engine.GetEventTypeRef(ref ev); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), engine.Log_GetEventNameById(nEventType), gameObject); #endif switch (nEventType) { case EngineConstants.EVENT_TYPE_ENTER: { int nAbility = engine.GetEventIntegerRef(ref ev, 0); GameObject oTarget = engine.GetEventTargetRef(ref ev); GameObject oCreator = engine.GetEventCreatorRef(ref ev); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "ENTER" + engine.ToString(oTarget), oCreator); #endif break; } case EngineConstants.EVENT_TYPE_EXIT: { int nAbility = engine.GetEventIntegerRef(ref ev, 0); GameObject oTarget = engine.GetEventTargetRef(ref ev); GameObject oCreator = engine.GetEventCreatorRef(ref ev); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "EXIT " + engine.ToString(oTarget), oCreator); #endif break; } } }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_ATTACK_IMPACT placeable event. * * The EngineConstants.EVENT_TYPE_ATTACK_IMPACT xEvent is triggered when a projectile fired by * the placeable strikes something (creature, placeable, surface, etc). The * xEvent fires once for all targets hit in a single frame. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleImpact(xEvent ev) { int i; List<GameObject> arTarget = new List<GameObject>(); //for (i = 1; IsObjectValid(GetEventObjectRef(ref ev, i)); i++) for (i = 1; i < ev.oList.Count; i++) { GameObject oObject = ev.oList.ElementAt(i); if (IsObjectValid(oObject) != EngineConstants.FALSE) { arTarget.Add(oObject); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "Target [" + IntToString(i) + "]: " + GetTag(GetEventObjectRef(ref ev, i))); } //perhaps in inner loop? if (i >= 2 && arTarget[i - 1] == arTarget[i - 2]) { arTarget[i - 1] = null; break; } } GameObject oAttacker = GetEventObjectRef(ref ev, 0); int nTargets = GetArraySize(arTarget); int nCombatResult = GetEventIntegerRef(ref ev, 0); int nProjectileType = GetEventIntegerRef(ref ev, 2); Vector3 lImpact = GetEventVectorRef(ref ev, 0); // position Vector3 lMissile = GetEventVectorRef(ref ev, 1); // orientation for (i = 0; i < nTargets; i++) { if (IsObjectValid(arTarget[i]) == EngineConstants.FALSE) break; // Apply damage to targets based on projectile type float fDamage = 0.0f; switch (nProjectileType) { case 51: // ballista bolt (from BITM_base.xls) { fDamage = 7.0f + RandomF(4, 1) * GetLevel(arTarget[i]); // base damage fDamage = DmgGetArmorMitigatedDamage(fDamage, 2.0f, arTarget[i]); break; } case 54: // big ballista bolt case 58: // same, climax only { // checking only first target as the archdemon ended up being hit 3 times // by the same bolt. fDamage = 50.0f + RandomF(4, 1) * GetLevel(arTarget[i]); // base damage fDamage = DmgGetArmorMitigatedDamage(fDamage, 5.0f, arTarget[i]); break; } default: Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", ToString(nProjectileType) + " *** Unhandled projectile type ***"); break; } xEffect eDamage = EffectDamage(fDamage, EngineConstants.DAMAGE_TYPE_PHYSICAL, EngineConstants.DAMAGE_EFFECT_FLAG_UPDATE_GORE | EngineConstants.DAMAGE_EFFECT_FLAG_CRITICAL); ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_INSTANT, eDamage, arTarget[i]); if (GetAppearanceType(arTarget[i]) == EngineConstants.APP_TYPE_ARCHDEMON) { if (nProjectileType == 54 || nProjectileType == 58) { oAttacker = GetLocalObject(oAttacker, EngineConstants.PLC_FLIP_COVER_CREATURE_1); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "attacker: " + GetTag(oAttacker)); } Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "ARCHDEMON!"); WR_ClearAllCommands(arTarget[i], EngineConstants.TRUE); xCommand cScream = CommandPlayAnimation(149); //xCommand cScream = CommandUseAbility(EngineConstants.MONSTER_HIGH_DRAGON_ROAR, arTarget[i]); WR_AddCommand(arTarget[i], cScream, EngineConstants.TRUE); // jump somewhere //List<GameObject> arWPs = GetNearestObjectByTag(arTarget[i], EngineConstants.AI_WP_MOVE, EngineConstants.OBJECT_TYPE_WAYPOINT, 2); //Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "Jump wps found: " + IntToString(GetArraySize(arWPs))); //GameObject oWP = arWPs[1]; // second farthest //if(IsObjectValid(oWP)) //{ // Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "JUMPING"); // xCommand cJump = CommandFly(GetLocation(oWP)); // WR_AddCommand(arTarget[i], cJump, EngineConstants.FALSE); //} // generate tons of threat against the shooter (from archdemon and anyone else around float fThreatChange = 150.0f; // Not updating for archdemon (too brutal) //AI_Threat_UpdateCreatureThreat(arTarget[i], oAttacker, fThreatChange); List<GameObject> arEnemies = GetNearestObjectByGroup(gameObject, EngineConstants.GROUP_HOSTILE, EngineConstants.OBJECT_TYPE_CREATURE, 10, EngineConstants.TRUE); int nSize = GetArraySize(arEnemies); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleImpact()", "found enemies: " + IntToString(nSize)); GameObject oCurrent; for (i = 0; i < nSize; i++) { oCurrent = arEnemies[i]; if (oCurrent != arTarget[i]) AI_Threat_UpdateCreatureThreat(oCurrent, oAttacker, fThreatChange); } } else { xEffect eKnockdown = EffectKnockdown(gameObject, 0); ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_INSTANT, eKnockdown, arTarget[i]); } } }
public void HandleEvent(xEvent ev) { //-------------------------------------------------------------------------- // Initialization //-------------------------------------------------------------------------- // Load engine.Event Variables //xEvent ev = engine.GetCurrentEvent(); // engine.Event int nEventType = engine.GetEventTypeRef(ref ev); // engine.Event Type GameObject oEventCreator = engine.GetEventCreatorRef(ref ev); // engine.Event Creator // Standard Stuff GameObject oPC = engine.GetHero(); int bEventHandled = EngineConstants.FALSE; //-------------------------------------------------------------------------- // Area engine.Events //-------------------------------------------------------------------------- switch (nEventType) { case EngineConstants.EVENT_TYPE_AREALOAD_SPECIAL: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_AREALOAD_SPECIAL: // Sent by: The engine // When: it is for playing things like cutscenes and movies when // you enter an area, things that do not involve AI or actual // game play. //------------------------------------------------------------------ break; } case EngineConstants.EVENT_TYPE_STEALING_SUCCESS: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_STEALING_SUCCESS: // Sent by: Skill Script (skill_stealing) // When: player succeeds stealing skill //------------------------------------------------------------------ engine.LogTrace(EngineConstants.LOG_CHANNEL_SYSTEMS, "orzar_core::EngineConstants.EVENT_TYPE_STEALING_SUCCESS", gameObject); //WR_SetPlotFlag(EngineConstants.PLT_GEN00PT_STEALING,STEALING_ORZ_COUNTER_INCREASE,EngineConstants.TRUE,EngineConstants.TRUE); break; } case EngineConstants.EVENT_TYPE_STEALING_FAILURE: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_STEALING_FAILURE: // Sent by: Skill Script (skill_stealing) // When: player fails stealing skill //------------------------------------------------------------------ engine.LogTrace(EngineConstants.LOG_CHANNEL_SYSTEMS, "orzar_core::EngineConstants.EVENT_TYPE_STEALING_FAILURE", gameObject); engine.WR_SetPlotFlag(EngineConstants.PLT_GEN00PT_STEALING, EngineConstants.STEALING_ORZ_COUNTER_INCREASE, EngineConstants.TRUE, EngineConstants.TRUE); // Trigger Guard Bark GameObject oNearestGuard = engine.UT_GetNearestObjectByTag(oPC, "orz300cr_guard_1"); if (engine.IsObjectValid(oNearestGuard) == EngineConstants.FALSE) oNearestGuard = engine.UT_GetNearestObjectByTag(oPC, "orz200cr_guard_1"); if (engine.IsObjectValid(oNearestGuard) != EngineConstants.FALSE) { engine.WR_ClearAllCommands(oNearestGuard); engine.WR_AddCommand(oNearestGuard, engine.CommandJumpToObject(oPC), EngineConstants.TRUE); engine.WR_SetPlotFlag(EngineConstants.PLT_GEN00PT_STEALING, EngineConstants.STEALING_ORZ_PC_CAUGHT_BY_GUARDS_STEALING, EngineConstants.TRUE); engine.UT_Talk(oNearestGuard, oNearestGuard); } break; } case EngineConstants.EVENT_TYPE_AREALOAD_PRELOADEXIT: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_AREALOAD_PRELOADEXIT: // Sent by: The engine // When: for things you want to happen while the load screen is // still up, things like moving creatures around. //------------------------------------------------------------------ int bBhelenKing; int bHarrowKing; int bParagonDone; //------------------------------------------------------------------ bBhelenKing = engine.WR_GetPlotFlag(EngineConstants.PLT_ORZPT_MAIN, EngineConstants.ORZ_MAIN___PLOT_04_BHELEN_CROWNED); bHarrowKing = engine.WR_GetPlotFlag(EngineConstants.PLT_ORZPT_MAIN, EngineConstants.ORZ_MAIN___PLOT_04_COMPLETED_KING_IS_HARROWMONT); //------------------------------------------------------------------ engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_POST_PLOT_BHELEN_KING, bBhelenKing); engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_POST_PLOT_HARROW_KING, bHarrowKing); engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_POST_PLOT_DONE, (bBhelenKing != EngineConstants.FALSE || bHarrowKing != EngineConstants.FALSE) ? EngineConstants.TRUE : EngineConstants.FALSE); engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_POST_PLOT_NOT_DONE, (bBhelenKing == EngineConstants.FALSE || bHarrowKing == EngineConstants.FALSE) ? EngineConstants.TRUE : EngineConstants.FALSE); // TEMP engine.ORZ_SetupGroupHostility(); engine.ORZ_SetupBackgroundKA(); //SetAtmosphericConditions(5); //SetCloudConditions(0); // END TEMP break; } case EngineConstants.EVENT_TYPE_AREALOAD_POSTLOADEXIT: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_AREALOAD_POSTLOADEXIT: // Sent by: The engine // When: fires at the same time that the load screen is going away, // and can be used for things that you want to make sure the player // sees. //------------------------------------------------------------------ break; } case EngineConstants.EVENT_TYPE_ENTER: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_ENTER: // Sent by: The engine // When: A creature enters the area. //------------------------------------------------------------------ break; } case EngineConstants.EVENT_TYPE_EXIT: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_EXIT: // Sent by: The engine // When: A creature exits the area. //------------------------------------------------------------------ break; } case EngineConstants.EVENT_TYPE_TEAM_DESTROYED: { //------------------------------------------------------------------ // EngineConstants.EVENT_TYPE_TEAM_DESTROYED: // Sent by: The engine // When: A creature's entire team dies //------------------------------------------------------------------ int nTeamID = engine.GetEventIntegerRef(ref ev, 0); switch (nTeamID) { case EngineConstants.ORZ_TEAM_PROHARROW_SUPPORTERS: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROHARROW_SUPPORTERS: // TEAM 1 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_EVENTS, EngineConstants.ORZ_EVENT_NOBLES_QUARTER_SUPPORTER_FIGHT_OVER_SIDED_BHELEN, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_PROBHELEN_SUPPORTERS: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROBHELEN_SUPPORTERS: // TEAM 2 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_EVENTS, EngineConstants.ORZ_EVENT_NOBLES_QUARTER_SUPPORTER_FIGHT_OVER_SIDED_HARROWMONT, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_DACE_AMBUSHERS_1: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_DACE_AMBUSHERS_1: // TEAM 5 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ340PT_FIND_LORD_DACE, EngineConstants.ORZ_DACE__EVENT_DACE_AMBUSH_SECOND_ROUND_SETUP, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_DACE_AMBUSHERS_2: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_DACE_AMBUSHERS_2: // TEAM 6 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ340PT_FIND_LORD_DACE, EngineConstants.ORZ_DACE__EVENT_DACE_AMBUSH_OVER, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_CARTA_ROGGAR: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARTA_ROGGAR: // TEAM 9 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ200PT_FIGALE, EngineConstants.ORZ_FIGALE_ROGGAR_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_AOTV_TRAP_1: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_AOTV_TRAP_1: // TEAM 13 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ540PT_ANVIL_OT_VOID, EngineConstants.ORZ_AOTV__EVENT_TRAP_1_SOLVED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_AOTV_TRAP_2: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_AOTV_TRAP_2: // TEAM 14 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ540PT_ANVIL_OT_VOID, EngineConstants.ORZ_AOTV__EVENT_TRAP_2_SOLVED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_CARTA_HOME_AMBUSHERS: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARTA_HOME_AMBUSHERS: // TEAM 17 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_CARTA, EngineConstants.ORZ_CARTA__EVENT_HOUSE_AMBUSH_LAST_THUG_SURRENDERS, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_ROGEK: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_ROGEK: // TEAM 18 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ400PT_ROGEK, EngineConstants.ORZ_ROGEK_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_BHELEN: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_BHELEN_ASSEMBLY: // TEAM 19 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ340PT_ASSEMBLY, EngineConstants.ORZ_ASSEMBLY_FINAL_SCENE_BHELEN_DEFEATED_AFTER_VOTE, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_IMREK: { //---------------------------------------------------------- // TEAM 26 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ100PT_IMREK, EngineConstants.ORZ_IMREK_IS_DEAD, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_KARDOL_DARKSPAWN_1: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_KARDOL_DARKSPAWN_1 // TEAM 30 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ550PT_KARDOL, EngineConstants.ORZ_KARDOL_INTRO_FIGHT_OVER, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_KARDOL_DARKSPAWN_4: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_KARDOL_DARKSPAWN_1 // TEAM 89 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ550PT_KARDOL, EngineConstants.ORZ_KARDOL_BRIDGE_CLEARED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_RUCK: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_RUCK: // TEAM 33 //---------------------------------------------------------- if (engine.WR_GetPlotFlag(EngineConstants.PLT_ORZ200PT_FILDA, EngineConstants.ORZ_FILDA___PLOT_ACTIVE) != EngineConstants.FALSE) engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ200PT_FILDA, EngineConstants.ORZ_FILDA___PLOT_02_RUCK_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_1: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_1: // TEAM 43 //---------------------------------------------------------- engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_2); break; } case EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_2: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_2: // TEAM 44 //---------------------------------------------------------- engine.UT_TeamAppears(EngineConstants.ORZ_TEAM_CARIDINS_CROSS_DSTALKER_NEST_3); break; } case EngineConstants.ORZ_TEAM_BRANKA_DARKSPAWN_WAVE_1: case EngineConstants.ORZ_TEAM_BRANKA_DARKSPAWN_WAVE_2: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_BRANKA_DARKSPAWN_WAVE_1/2 // TEAM 50/ 51 //---------------------------------------------------------- GameObject oBranka = engine.GetObjectByTag(EngineConstants.ORZ_CR_BRANKA); engine.UT_Talk(oBranka, oBranka, "", EngineConstants.FALSE); break; } case EngineConstants.ORZ_TEAM_PALACE_THIEVES: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PALACE_THIEVES // TEAM 55 //---------------------------------------------------------- GameObject oGaurd, oWaypoint; oGaurd = engine.GetObjectByTag(EngineConstants.ORZ_CR_TUNNELING_THIEF_GUARD); oWaypoint = engine.GetObjectByTag(EngineConstants.ORZ_WP_GAURD_MOVETO); engine.WR_SetObjectActive(oGaurd, EngineConstants.TRUE); engine.AddCommand(oGaurd, engine.CommandMoveToObject(oWaypoint), EngineConstants.TRUE); engine.UT_Talk(oGaurd, oPC); break; } case EngineConstants.ORZ_TEAM_PROVING_LITE_1: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROVING_LITE_1 // TEAM 66 //---------------------------------------------------------- engine.ORZ_CleanUpLiteProving(); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHT_WON, EngineConstants.TRUE, EngineConstants.TRUE); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHTS_WON_01, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_PROVING_LITE_2: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROVING_LITE_2 // TEAM 67 //---------------------------------------------------------- engine.ORZ_CleanUpLiteProving(); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHT_WON, EngineConstants.TRUE, EngineConstants.TRUE); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHTS_WON_02, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_PROVING_LITE_3: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROVING_LITE_3 // TEAM 68 //---------------------------------------------------------- engine.ORZ_CleanUpLiteProving(); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHT_WON, EngineConstants.TRUE, EngineConstants.TRUE); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHTS_WON_03, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_PROVING_LITE_4: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_PROVING_LITE_4 // TEAM 69 //---------------------------------------------------------- engine.ORZ_CleanUpLiteProving(); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHT_WON, EngineConstants.TRUE, EngineConstants.TRUE); engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ260PT_LITE_PROVING, EngineConstants.ORZ_LTP_FIGHTS_WON_04, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_AMBASSADOR: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_AMBASSADOR // TEAM 900 //---------------------------------------------------------- // LC: For the Denerim Assassination Missions engine.WR_SetPlotFlag(EngineConstants.PLT_DEN200PT_ASSASSIN_ORZ, EngineConstants.AMBASSADOR_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_CARIDIN_GOLEMS: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARIDIN_GOLEMS // TEAM 16 //---------------------------------------------------------- // Update plot depending on who you sided with if (engine.WR_GetPlotFlag(EngineConstants.PLT_ORZPT_ANVIL, EngineConstants.ORZ_ANVIL_CARIDIN_ATTACKS) != EngineConstants.FALSE) engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_ANVIL, EngineConstants.ORZ_ANVIL___PLOT_07_CARIDIN_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); else engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_ANVIL, EngineConstants.ORZ_ANVIL___PLOT_07_BRANKA_KILLED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_BROODMOTHER: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_BROODMOTHER // TEAM 78 //---------------------------------------------------------- // Hespith has something to say engine.WR_SetPlotFlag(EngineConstants.PLT_ORZ550PT_HESPITH, EngineConstants.ORZ_HESPITH_BROODMOTHER_DEFEATED, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_CARTA_JARVIA: { //---------------------------------------------------------- // EngineConstants.ORZ_TEAM_CARTA_JARVIA // TEAM 8 //---------------------------------------------------------- engine.WR_SetPlotFlag(EngineConstants.PLT_ORZPT_CARTA, EngineConstants.ORZ_CARTA_JARVIA_DEAD, EngineConstants.TRUE, EngineConstants.TRUE); break; } case EngineConstants.ORZ_TEAM_SPIDER_QUEEN_SPIDERLINGS: case EngineConstants.ORZ_TEAM_SPIDER_QUEEN_SPIDERLINGS_2: { GameObject oSpiderQueen = engine.UT_GetNearestCreatureByTag(oPC, EngineConstants.ORZ_CR_QUEEN_SPIDER); engine.SignalEvent(oSpiderQueen, engine.Event(EngineConstants.EVENT_TYPE_CUSTOM_EVENT_01)); break; } case EngineConstants.ORZ_TEAM_SPIDER_QUEEN: { GameObject oBrankaJournal = engine.UT_GetNearestObjectByTag(oPC, EngineConstants.ORZ_IP_BRANKA_JOURNAL); // Branka's journal can now be interacted with engine.SetObjectInteractive(oBrankaJournal, EngineConstants.TRUE); break; } } bEventHandled = EngineConstants.TRUE; break; } } //-------------------------------------------------------------------------- // Pass any unhandled events to area_core //-------------------------------------------------------------------------- if (bEventHandled == EngineConstants.FALSE) engine.HandleEventRef(ref ev, EngineConstants.RESOURCE_SCRIPT_AREA_CORE); }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_USE placeable event. * * This xEvent handler uses GetPlaceableAction() to identify the specific action * that triggered the xEvent (i.e. placeable was used, opened, unlocked, etc.) and * SetPlaceableActionResult() to trigger a state change based on the result of * the action. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleUsed(xEvent ev) { GameObject oThis = gameObject; GameObject oUser = GetEventCreatorRef(ref ev); int nAction = GetPlaceableAction(gameObject); int nActionResult = EngineConstants.TRUE; int bVariation = GetEventIntegerRef(ref ev, 0); // if true, Success0A column chosen in 2DA // (used to make door always open away from player) if (GetObjectActive(gameObject) == EngineConstants.FALSE) return; Placeable_ShowCodexEntry(gameObject); switch (nAction) { case EngineConstants.PLACEABLE_ACTION_USE: { break; } case EngineConstants.PLACEABLE_ACTION_OPEN: { Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleUsed()", "Variation: " + ToString(bVariation)); // For doors, bVariation is 1/0 to indicate the player is using it from the front/back. // However, the Success0 column should be used by SetPlaceableActionResult() if the player // is using the door from the front and Success0A column if from the back. To facilitate // this logic, simply invert the value of bVariation. //bVariation = !bVariation; bVariation = (bVariation + 1 == 1) ? EngineConstants.TRUE : EngineConstants.FALSE; // PrxEvent use of containers during combat. string sController = GetPlaceableStateCntTable(gameObject); if (GetGameMode() == EngineConstants.GM_COMBAT && (sController == EngineConstants.PLC_STATE_CNT_CONTAINER_STATIC || sController == EngineConstants.PLC_STATE_CNT_CONTAINER || sController == EngineConstants.PLC_STATE_CNT_BODYBAG)) { UI_DisplayMessage(oUser, EngineConstants.UI_MESSAGE_CANT_DO_IN_COMBAT); nActionResult = EngineConstants.FALSE; } else { SendEventOpened(gameObject, oUser); } break; } case EngineConstants.PLACEABLE_ACTION_CLOSE: { break; } case EngineConstants.PLACEABLE_ACTION_AREA_TRANSITION: { Placeable_DoAreaTransition(gameObject); break; } case EngineConstants.PLACEABLE_ACTION_CONVERSATION: { if (HasConversation(gameObject) != EngineConstants.FALSE && GetCombatState(oUser) == EngineConstants.FALSE) { BeginConversation(oUser, gameObject); } break; } case EngineConstants.PLACEABLE_ACTION_EXAMINE: { if (UI_DisplayPopupText(gameObject, gameObject) == EngineConstants.FALSE) { if (HasConversation(gameObject) != EngineConstants.FALSE && GetCombatState(oUser) == EngineConstants.FALSE) BeginConversation(oUser, gameObject); } break; } case EngineConstants.PLACEABLE_ACTION_TRIGGER_TRAP: { break; } case EngineConstants.PLACEABLE_ACTION_DISARM: { if (HasAbility(oUser, EngineConstants.ABILITY_TALENT_HIDDEN_ROGUE) == EngineConstants.FALSE) { // Only rogues can disarm traps nActionResult = EngineConstants.FALSE; } // Trap detection difficulty property is used instead of trap disarm property // because as a rule any trap you can detect you should be able to disarm. // It's easier to enforce this in screipt than check every trap placed in // every level of the game. int nTargetScore = GetTrapDisarmDifficulty(gameObject); int nPlayerScore = FloatToInt(GetDisableDeviceLevel(oUser)); if (nActionResult != EngineConstants.FALSE) { if (Trap_GetOwner(gameObject) == oUser) { // Can always disarm your own traps nActionResult = EngineConstants.TRUE; } else { Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName(), "Player score: " + ToString(nPlayerScore) + " vs Disarm Level: " + ToString(nTargetScore)); nActionResult = (nPlayerScore >= nTargetScore) ? EngineConstants.TRUE : EngineConstants.FALSE; } WR_AddCommand(oUser, CommandPlayAnimation(904)); if (nActionResult != EngineConstants.FALSE) { // Can only disarm a trap once. if (GetLocalInt(gameObject, EngineConstants.PLC_DO_ONCE_A) == EngineConstants.FALSE) { SetLocalInt(gameObject, EngineConstants.PLC_DO_ONCE_A, EngineConstants.TRUE); // Slight delay to account for disarm animation. Trap_SignalDisarmEvent(gameObject, oUser, 3.0f); } } else { if (nTargetScore >= EngineConstants.DEVICE_DIFFICULTY_IMPOSSIBLE) { UI_DisplayMessage(oUser, EngineConstants.UI_MESSAGE_DISARM_NOT_POSSIBLE); } else { UI_DisplayMessage(oUser, EngineConstants.TRAP_DISARM_FAILED); SSPartyMemberComment(EngineConstants.CLASS_ROGUE, EngineConstants.SOUND_SITUATION_SKILL_FAILURE, oUser); } Trap_SignalTeam(gameObject); PlaySound(gameObject, EngineConstants.SOUND_TRAP_DISARM_FAILURE); } } else { UI_DisplayMessage(oUser, EngineConstants.TRAP_DISARM_FAILED); Trap_SignalTeam(gameObject); } break; } case EngineConstants.PLACEABLE_ACTION_UNLOCK: { int nLockLevel = GetPlaceablePickLockLevel(gameObject); int bRemoveKey = GetPlaceableAutoRemoveKey(gameObject); int bKeyRequired = GetPlaceableKeyRequired(gameObject); string sKeyTag = GetPlaceableKeyTag(gameObject); int bUsedKey = EngineConstants.FALSE; if (IsPartyMember(oUser) != EngineConstants.FALSE) { WR_SetPlotFlag(EngineConstants.PLT_TUT_PLACEABLE_LOCKED, EngineConstants.TUT_PLACEABLE_LOCKED_ENCOUNTER_1, EngineConstants.TRUE); } // Set ActionResult to reflect the 'unlocked' state nActionResult = EngineConstants.FALSE; // Attempt to use key if (sKeyTag != "") { GameObject oKey = GetItemPossessedBy(oUser, sKeyTag); if (IsObjectValid(oKey) != EngineConstants.FALSE) { bUsedKey = EngineConstants.TRUE; nActionResult = EngineConstants.TRUE; if (bRemoveKey != EngineConstants.FALSE) DestroyObject(oKey, 0); } } int bLockPickable = (nLockLevel < EngineConstants.DEVICE_DIFFICULTY_IMPOSSIBLE) ? EngineConstants.TRUE : EngineConstants.FALSE; if (bLockPickable != EngineConstants.FALSE) { // If still locked and key not required then rogues can attempt to pick lock. if (nActionResult == EngineConstants.FALSE && bKeyRequired == EngineConstants.FALSE && HasAbility(oUser, EngineConstants.ABILITY_TALENT_HIDDEN_ROGUE) != EngineConstants.FALSE) { // player score float fPlayerScore = GetDisableDeviceLevel(oUser); float fTargetScore = IntToFloat(nLockLevel); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName(), "nLockLevel = " + ToString(nLockLevel)); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName(), "Final Value = " + ToString(fPlayerScore)); nActionResult = (fPlayerScore >= fTargetScore) ? EngineConstants.TRUE : EngineConstants.FALSE; } } if (nActionResult != EngineConstants.FALSE) { // Success UI_DisplayMessage(gameObject, (bUsedKey != EngineConstants.FALSE ? EngineConstants.UI_MESSAGE_UNLOCKED_BY_KEY : EngineConstants.UI_MESSAGE_UNLOCKED)); PlaySound(gameObject, GetM2DAString(EngineConstants.TABLE_PLACEABLE_TYPES, "PickLockSuccess", GetAppearanceType(gameObject))); if (bKeyRequired == EngineConstants.FALSE) AwardDisableDeviceXP(oUser, nLockLevel); } else {//` if (bKeyRequired != EngineConstants.FALSE) { UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_KEY_REQUIRED); } else { if (bLockPickable == EngineConstants.FALSE) { UI_DisplayMessage(oUser, EngineConstants.UI_MESSAGE_LOCKPICK_NOT_POSSIBLE); } else { UI_DisplayMessage(oUser, EngineConstants.UI_MESSAGE_UNLOCK_SKILL_LOW); SSPartyMemberComment(EngineConstants.CLASS_ROGUE, EngineConstants.SOUND_SITUATION_SKILL_FAILURE, oUser); } } PlaySound(gameObject, GetM2DAString(EngineConstants.TABLE_PLACEABLE_TYPES, "PickLockFailure", GetAppearanceType(gameObject))); } //increment unlocking achievement if (nActionResult != EngineConstants.FALSE && bUsedKey == EngineConstants.FALSE) { ACH_LockpickAchievement(oUser); } // Signal result to self. xEvent evResult = Event(nActionResult != EngineConstants.FALSE ? EngineConstants.EVENT_TYPE_UNLOCKED : EngineConstants.EVENT_TYPE_UNLOCK_FAILED); SetEventObjectRef(ref evResult, 0, oUser); SignalEvent(gameObject, evResult); break; } case EngineConstants.PLACEABLE_ACTION_OPEN_INVENTORY: { SendEventOpened(gameObject, oUser); if (IsBodyBag(gameObject) != EngineConstants.FALSE) { // get number of inventory items List<GameObject> oInventory = GetItemsInInventory(gameObject, EngineConstants.GET_ITEMS_OPTION_ALL); int nSize1 = GetArraySize(oInventory); // if inventory exists if (nSize1 > 0) { // get number of money items List<GameObject> oMoney = GetItemsInInventory(gameObject, EngineConstants.GET_ITEMS_OPTION_ALL, 0, "gen_im_copper"); int nSize2 = GetArraySize(oMoney); // if the only items are money items if (nSize1 == nSize2) { // add money stack sizes and delete objects int nMoney = 0; int nCount = 0; for (nCount = 0; nCount < nSize2; nCount++) { nMoney += GetItemStackSize(oMoney[nCount]); Safe_Destroy_Object(oMoney[nCount], 0); } // add money directly to looter AddCreatureMoney(nMoney, oUser); } else { OpenInventory(gameObject, oUser); } } else { OpenInventory(gameObject, oUser); } } else { if (FindSubString(GetTag(gameObject), "_autoloot") >= 0) { MoveAllItems(gameObject, oUser); } else { OpenInventory(gameObject, oUser); } } if (GetLocalInt(GetModule(), EngineConstants.TUTORIAL_ENABLED) != EngineConstants.FALSE) WR_SetPlotFlag(EngineConstants.PLT_TUT_INVENTORY, EngineConstants.TUT_INVENTORY_1, EngineConstants.TRUE); break; } case EngineConstants.PLACEABLE_ACTION_FLIP_COVER: { break; } case EngineConstants.PLACEABLE_ACTION_USE_COVER: { // Store user so they can be un-crouched if placeable is destroyed. SetLocalObject(gameObject, EngineConstants.PLC_FLIP_COVER_CREATURE_1, oUser); break; } case EngineConstants.PLACEABLE_ACTION_LEAVE_COVER: { SetLocalObject(gameObject, EngineConstants.PLC_FLIP_COVER_CREATURE_1, null); break; } case EngineConstants.PLACEABLE_ACTION_TOPPLE: { break; } case EngineConstants.PLACEABLE_ACTION_DESTROY: { // Remove stealth if (IsStealthy(oUser) != EngineConstants.FALSE) SetStealthEnabled(oUser, EngineConstants.FALSE); // Make user attack placeable WR_AddCommand(oUser, CommandAttack(gameObject)); // Return (instead of break) since the action result for the // destroy action is set by the death xEvent handler (i.e. the // destroy action succeeds when the placeable reaches 0 health). return; } case EngineConstants.PLACEABLE_ACTION_TURN_LEFT: { // large ballista rotation (activated on base) // Find nearest large ballista GameObject and rotate to match base rotation GameObject oTop = UT_GetNearestObjectByTag(gameObject, EngineConstants.PLC_TAG_BIG_BALLISTA); if (IsObjectValid(oTop) != EngineConstants.FALSE) { SetFacing(oTop, GetFacing(oTop) - 15.0f); } PlaySound(gameObject, "glo_fly_plc/placeables/ballista_mount/ballista_mount"); break; } case EngineConstants.PLACEABLE_ACTION_TURN_RIGHT: { // large ballista rotation (activated on base) // Find nearest large ballista GameObject and rotate to match base rotation GameObject oTop = UT_GetNearestObjectByTag(gameObject, EngineConstants.PLC_TAG_BIG_BALLISTA); if (IsObjectValid(oTop) != EngineConstants.FALSE) { SetFacing(oTop, GetFacing(oTop) + 15.0f); } PlaySound(gameObject, "glo_fly_plc/placeables/ballista_mount/ballista_mount"); break; } default: { Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleUsed", "PLACEABLE_ACTION (" + ToString(nAction) + ") *** Unhandled action ***"); break; } } //TrackPlaceableEvent(GetEventTypeRef(ref ev), gameObject, oUser, nAction, nActionResult); // Action result determines next state transition. SetPlaceableActionResult(gameObject, nAction, nActionResult, bVariation); }
//------------------------------------------------------------------------------ public void ORZ_BrankaCaridin_HandleEventLavaQuake(xEvent evEvent) { int nLoopNum = GetEventIntegerRef(ref evEvent, 0); int nLoopGroup = GetEventIntegerRef(ref evEvent, 1); GameObject oCaridin = GetObjectByTag(EngineConstants.ORZ_CR_CARIDIN); xEffect effEruption = EffectVisualEffect(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_ERUPTION_VFX); List<GameObject> arTargets = GetNearestObjectByTag(oCaridin, EngineConstants.ORZ_ANVIL_WP_LAVA_QUAKE_PREFIX + ToString(nLoopGroup), EngineConstants.OBJECT_TYPE_WAYPOINT, EngineConstants.ORZ_ANVIL_LAVA_QUAKE_MAX_ERUPTIONS); int nNumTargets, nNumCreatures, i, k; Vector3 evLocation; List<GameObject> arNearestCreatures; if (IsDeadOrDying(oCaridin) == EngineConstants.FALSE && GetCombatState(oCaridin) != EngineConstants.FALSE) { // Loop through the waypoints nNumTargets = GetArraySize(arTargets); for (i = 0; i < nNumTargets; i++) { evLocation = GetLocation(arTargets[i]); Vector3 vPos = GetPositionFromLocation(evLocation); vPos.z += 0.25f; SetLocationPosition(evLocation, vPos); xEffect eAoE = EffectAreaOfEffect(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_AOE_ID, "orz540_lava_aoe.ncs", EngineConstants.ORZ_ANVIL_LAVA_QUAKE_ERUPTION_VFX); Engine_ApplyEffectAtLocation(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, eAoE, evLocation, EngineConstants.ORZ_ANVIL_LAVA_QUAKE_GROUP_DELAY, oCaridin, EngineConstants.ORZ_ANVIL_LAVA_QUAKE_ABILITY_ID); } // Apply an earthquake VFX and screenshake ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, EffectVisualEffect(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_EARTHQUAKE_VFX), oCaridin, 5.0f); ApplyEffectOnParty(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, EffectScreenShake(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_SCREENSHAKE_ID), 3.0f); // Resend the xEvent back to the area, with a different // lava_quake group for the next round SetEventIntegerRef(ref evEvent, 0, (nLoopNum + 1)); SetEventIntegerRef(ref evEvent, 1, ((nLoopGroup + 1) % EngineConstants.ORZ_ANVIL_LAVA_QUAKE_NUM_GROUPS)); DelayEvent(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_GROUP_DELAY, gameObject, evEvent); } }
//------------------------------------------------------------------------------ public void ORZ_BrankaCaridin_HandleEventRockFallImpact(xEvent evEvent) { Vector3 evLocation = GetEventVectorRef(ref evEvent, 0); GameObject oBranka = GetObjectByTag(EngineConstants.ORZ_CR_BRANKA); List<GameObject> arNearestCreatures = GetObjectsInShape(EngineConstants.OBJECT_TYPE_CREATURE, EngineConstants.SHAPE_SPHERE, evLocation, 2.0f); int i, size = GetArraySize(arNearestCreatures); float fDifficultyMod = GetGameDifficulty() * 0.5f + 0.5f; float fDamage = EngineConstants.ORZ_ANVIL_ROCK_FALL_DAMAGE * fDifficultyMod; GameObject oTarget; Engine_ApplyEffectAtLocation(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, EffectVisualEffect(90146), evLocation, 2.0f); for (i = 0; i < size; i++) { oTarget = arNearestCreatures[i]; if (ResistanceCheck(oBranka, oTarget, EngineConstants.PROPERTY_ATTRIBUTE_STRENGTH, EngineConstants.RESISTANCE_PHYSICAL) == EngineConstants.FALSE) { if (IsObjectHostile(oBranka, oTarget) != EngineConstants.FALSE || oTarget == oBranka) DamageCreature(oTarget, gameObject, fDamage, EngineConstants.DAMAGE_TYPE_PHYSICAL); } } }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_COMMAND_COMPLETE placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleCommandCompleted(xEvent ev) { // int nLastCommandType = GetEventIntegerRef(ref ev, 0); // int nCommandStatus = GetEventIntegerRef(ref ev, 1); // int nLastSubCommand = GetEventIntegerRef(ref ev, 2); }
//------------------------------------------------------------------------------ public void ORZ_BrankaCaridin_HandleEventBrankaIllusion(xEvent evEvent) { GameObject oBranka = UT_GetNearestObjectByTag(GetHero(), EngineConstants.ORZ_CR_BRANKA); GameObject oArea = GetArea(oBranka); float fFacing = GetFacing(oBranka); Vector3 loc = GetEventVectorRef(ref evEvent, 0); Vector3 vPos = GetPositionFromLocation(loc); Vector3 vBranka = GetPosition(oBranka); Vector3 vDiff = Vector(vPos.x - vBranka.x, vPos.y - vBranka.y, 0.0f); xEffect effMod = EffectModifyAttribute(EngineConstants.ATTRIBUTE_STR, FloatToInt(GetCreatureAttribute(oBranka, EngineConstants.ATTRIBUTE_STR) * 0.8f) * -1); List<GameObject> arClones = UT_GetAllObjectsInAreaByTag(EngineConstants.ORZ_CR_BRANKA_CLONE); List<GameObject> arParty = GetPartyList(); int nPartySize = GetArraySize(arParty); List<Vector3> arLocs = new List<Vector3>(); arLocs[0] = GetSafeLocation(GetLocation(oBranka)); arLocs[1] = GetSafeLocation(Location(oArea, Vector(vPos.x - vDiff.y, vPos.y + vDiff.x, vPos.z + 1.0f), fFacing + 90.0f)); arLocs[2] = GetSafeLocation(Location(oArea, Vector(vPos.x + vDiff.y, vPos.y - vDiff.x, vPos.z + 1.0f), fFacing - 90.0f)); arLocs[3] = GetSafeLocation(Location(oArea, Vector(vPos.x + vDiff.x, vPos.y + vDiff.y, vPos.z + 1.0f), fFacing + 180.0f)); int nBrankaLoc = Engine_Random(3) + 1; WR_AddCommand(oBranka, CommandJumpToLocation(arLocs[nBrankaLoc++]), EngineConstants.TRUE); WR_SetObjectActive(oBranka, EngineConstants.TRUE); UT_CombatStart(oBranka, arParty[nBrankaLoc % nPartySize], EngineConstants.TRUE); ApplyEffectVisualEffect(oBranka, oBranka, EngineConstants.STEALTH_IMPACT_VFX, EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, 2.0f); int i; for (i = 0; i < 3; i++) { _CreateIllusionCopy(arClones[i], arLocs[(nBrankaLoc + i) % 4], effMod, oBranka); UT_CombatStart(arClones[i], arParty[(nBrankaLoc + i) % nPartySize], EngineConstants.TRUE); //WR_AddCommand(arClones[i],CommandWait(1.0f)); //WR_AddCommand(arClones[i],CommandPlayAnimation(EngineConstants.COMBAT_ANIMATION_ENTER_BERSERK,0,0,0),EngineConstants.FALSE,EngineConstants.TRUE); //ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY,EffectParalyze(),arClones[i],1.0f); ApplyEffectVisualEffect(oBranka, arClones[i], EngineConstants.STEALTH_IMPACT_VFX, EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, 2.0f); } }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_DAMAGED placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleDamaged(xEvent ev) { GameObject oDamager = GetEventCreatorRef(ref ev); float fDamage = GetEventFloatRef(ref ev, 0); int nDamageType = GetEventIntegerRef(ref ev, 0); // Outside of combat, force damager to continue bashing placeable if (GetGameMode() == EngineConstants.GM_EXPLORE && GetCurrentHealth(gameObject) > 0.0f) { WR_AddCommand(oDamager, CommandAttack(gameObject)); } }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_DEATH placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleDeath(xEvent ev) { GameObject oKiller = GetEventCreatorRef(ref ev); // Play death visual effect int nType = GetAppearanceType(gameObject); int nVFX = GetM2DAInt(EngineConstants.TABLE_PLACEABLE_TYPES, "DestroyVFX", nType); if (nVFX != EngineConstants.FALSE) { ApplyEffectVisualEffect(gameObject, gameObject, nVFX, EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, 1.5f); } // Determine angle to last attacker for doors and set variation accordingly. int bVariation = EngineConstants.TRUE; if (GetPlaceableStateCntTable(gameObject) == EngineConstants.PLC_STATE_CONTROLLER_DOOR) { float fAngle = GetAngleBetweenObjects(gameObject, oKiller); Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleDeath()", "fAngle: " + ToString(fAngle)); if (fAngle < 90.0f || fAngle > 270.0f) bVariation = EngineConstants.FALSE; } // The result of the destroy action is set in the death xEvent handler since // the destroy action 'succeeds' only when the placeable reaches 0 health. //SetPlaceableActionResult(gameObject, EngineConstants.PLACEABLE_ACTION_DESTROY, EngineConstants.TRUE, bVariation); string sStateTable = GetPlaceableStateCntTable(gameObject); int nDeathState = 0; if (sStateTable == "StateCnt_Furniture" || sStateTable == "StateCnt_Puzzle" || sStateTable == "StateCnt_Static") nDeathState = 1; else if (sStateTable == "StateCnt_AOE" || sStateTable == "StateCnt_FlipCover" || sStateTable == "StateCnt_Selectable_Trap" || sStateTable == "StateCnt_Container_Static" || sStateTable == "StateCnt_Trigger" || sStateTable == "StateCnt_Door_Secret") nDeathState = 2; else if (sStateTable == "StateCnt_Cage" || sStateTable == "StateCnt_Container" || sStateTable == "StateCnt_BBase" || sStateTable == "StateCnt_Door") nDeathState = 3; SetPlaceableState(gameObject, nDeathState); // If killer is not in combat, stop attacking placeable. if (GetGameMode() == EngineConstants.GM_EXPLORE) { //WR_ClearAllCommands(oKiller); WR_AddCommand(oKiller, CommandWait(2.0f)); WR_AddCommand(oKiller, CommandSheatheWeapons()); } // Damage contents of containers. List<GameObject> aItems = GetItemsInInventory(gameObject); int nItems = GetArraySize(aItems); if (nItems > 0) { int i; for (i = 0; i < nItems; i++) { int n = GetItemStackSize(aItems[i]); if (n > 1) { SetItemStackSize(aItems[i], n / 2); } else if (IsPlot(aItems[i]) != EngineConstants.FALSE && GetItemEquipSlotMask(GetBaseItemType(aItems[i])) != EngineConstants.FALSE && Engine_Random(2) > 1)//>1 added by DHK { //SetItemDamaged(aItems[i], EngineConstants.TRUE);//deprecated Warning("set item damaged used in DA:O was deprecated in DA2…"); } } } // Debug - set inactive if (GetPlaceableBaseType(gameObject) == 220) SetObjectActive(gameObject, EngineConstants.FALSE); // //Track death for game metrics //TrackObjectDeath(ev); }
/*---------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_ATTACKED placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleAttacked(xEvent ev) { GameObject oAttacker = GetEventCreatorRef(ref ev); }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_INVENTORY_* placeable events. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleInventory(xEvent ev) { GameObject oOwner = GetEventCreatorRef(ref ev); // Previous owner GameObject oItem = GetEventObjectRef(ref ev, 0); // item added/removed switch (GetEventTypeRef(ref ev)) { case EngineConstants.EVENT_TYPE_INVENTORY_ADDED: { break; } case EngineConstants.EVENT_TYPE_INVENTORY_REMOVED: { break; } } }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_CONVERSATION placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleDialog(xEvent ev) { GameObject oInitiator = GetEventCreatorRef(ref ev); // Player or NPC to talk to. string rConversation = GetEventResourceRef(ref ev, 0); // Conversation to play. if (GetCombatState(oInitiator) == EngineConstants.FALSE) { UT_Talk(gameObject, oInitiator); } }
void HandleCommandResult() { xEvent ev = new xEvent(EngineConstants.EVENT_TYPE_COMMAND_COMPLETE); engine.SetEventIntegerRef(ref ev, 0, currentCommand.nType);//Command type engine.SetEventIntegerRef(ref ev, 1, lastCommand.nResult);//Command result engine.SetEventObjectRef(ref ev, 0, gameObject);//Target engine.SignalEvent(gameObject, ev); cProgress = EngineConstants.FALSE;//Finished with a current command lastCommand = currentCommand; if (qCommand.Count == 0) currentCommand = engine.Command(EngineConstants.COMMAND_TYPE_INVALID);//Reset }
public override int StartingConditional(xEvent eParms) { //xEvent eParms = engine.GetCurrentEvent(); // Contains all input parameters int nType = engine.GetEventTypeRef(ref eParms); // GET or SET call string strPlot = engine.GetEventStringRef(ref eParms, 0); // Plot GUID int nFlag = engine.GetEventIntegerRef(ref eParms, 1); // The bit flag # being affected int nValue = engine.GetEventIntegerRef(ref eParms, 2); // On SET call, the value about to be written int nOldValue = engine.GetEventIntegerRef(ref eParms, 3); // On SET call, the current flag value GameObject oParty = engine.GetEventCreatorRef(ref eParms); // The owner of the plot table for this script int nResult = EngineConstants.FALSE; engine.plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info GameObject oPC = engine.GetHero(); if (nType == EngineConstants.EVENT_TYPE_SET_PLOT) // actions -> normal flags only { switch (nFlag) { default: break; } } else // EVENT_TYPE_GET_PLOT -> defined conditions only { int nSkill = 0; int nLevel = 0; switch (nFlag) { case EngineConstants.GEN_PERSUADE_LOW: nSkill = EngineConstants.SKILL_PERSUADE; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_PERSUADE_MED: nSkill = EngineConstants.SKILL_PERSUADE; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_PERSUADE_HIGH: nSkill = EngineConstants.SKILL_PERSUADE; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_PERSUADE_VERY_HIGH: nSkill = EngineConstants.SKILL_PERSUADE; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_HERBALISM_LOW: nSkill = EngineConstants.SKILL_HERBALISM; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_HERBALISM_MED: nSkill = EngineConstants.SKILL_HERBALISM; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_HERBALISM_HIGH: nSkill = EngineConstants.SKILL_HERBALISM; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_HERBALISM_VERY_HIGH: nSkill = EngineConstants.SKILL_HERBALISM; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_POISON_LOW: nSkill = EngineConstants.SKILL_POSION; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_POISON_MED: nSkill = EngineConstants.SKILL_POSION; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_POISON_HIGH: nSkill = EngineConstants.SKILL_POSION; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_POISON_VERY_HIGH: nSkill = EngineConstants.SKILL_POSION; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_TRAPS_LOW: nSkill = EngineConstants.SKILL_TRAPS; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_TRAPS_MED: nSkill = EngineConstants.SKILL_TRAPS; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_TRAPS_HIGH: nSkill = EngineConstants.SKILL_TRAPS; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_TRAPS_VERY_HIGH: nSkill = EngineConstants.SKILL_TRAPS; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_STEALTH_LOW: nSkill = EngineConstants.SKILL_STEALTH; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_STEALTH_MED: nSkill = EngineConstants.SKILL_STEALTH; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_STEALTH_HIGH: nSkill = EngineConstants.SKILL_STEALTH; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_STEALTH_VERY_HIGH: nSkill = EngineConstants.SKILL_STEALTH; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_STEALING_LOW: nSkill = EngineConstants.SKILL_STEALING; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_STEALING_MED: nSkill = EngineConstants.SKILL_STEALING; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_STEALING_HIGH: nSkill = EngineConstants.SKILL_STEALING; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_STEALING_VERY_HIGH: nSkill = EngineConstants.SKILL_STEALING; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_SURVIVAL_LOW: nSkill = EngineConstants.SKILL_SURVIVAL; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_SURVIVAL_MED: nSkill = EngineConstants.SKILL_SURVIVAL; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_SURVIVAL_HIGH: nSkill = EngineConstants.SKILL_SURVIVAL; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_SURVIVAL_VERY_HIGH: nSkill = EngineConstants.SKILL_SURVIVAL; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_LOCKPICKING_LOW: nSkill = EngineConstants.SKILL_LOCKPICKING; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_LOCKPICKING_MED: nSkill = EngineConstants.SKILL_LOCKPICKING; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_LOCKPICKING_HIGH: nSkill = EngineConstants.SKILL_LOCKPICKING; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_LOCKPICKING_VERY_HIGH: nSkill = EngineConstants.SKILL_LOCKPICKING; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; case EngineConstants.GEN_INTIMIDATE_LOW: nSkill = EngineConstants.SKILL_INTIMIDATE; nLevel = EngineConstants.UT_SKILL_CHECK_LOW; break; case EngineConstants.GEN_INTIMIDATE_MED: nSkill = EngineConstants.SKILL_INTIMIDATE; nLevel = EngineConstants.UT_SKILL_CHECK_MED; break; case EngineConstants.GEN_INTIMIDATE_HIGH: nSkill = EngineConstants.SKILL_INTIMIDATE; nLevel = EngineConstants.UT_SKILL_CHECK_HIGH; break; case EngineConstants.GEN_INTIMIDATE_VERY_HIGH: nSkill = EngineConstants.SKILL_INTIMIDATE; nLevel = EngineConstants.UT_SKILL_CHECK_VERY_HIGH; break; } nResult = engine.UT_SkillCheck(nSkill, nLevel, oPC); engine.ACH_CheckPersuadeAchievement(oPC, nResult, nSkill, EngineConstants.SKILL_PERSUADE); engine.ACH_CheckIntimidateAchievement(oPC, nResult, nSkill, EngineConstants.SKILL_INTIMIDATE); } engine.plot_OutputDefinedFlag(eParms, nResult); return nResult; }
// </Debug> // ----------------------------------------------------------------------------- // This handles rules_core.EVENT_TYPE_APPLY_EFFECT. // ----------------------------------------------------------------------------- public int Effects_HandleApplyEffect(xEvent ev) { xEffect eEffect = GetCurrentEffect(); int nEffectType = GetEffectTypeRef(ref eEffect); int nReturnValue = -1; GameObject oCreator = GetEffectCreatorRef(ref eEffect); int nAbilityId = GetEffectAbilityIDRef(ref eEffect); // <Debug> // ------------------------------------------------------------------------- // If logging is enabled, we also verify that the xEffect we are trying to // apply here is applied with an allowed duration type. if not, fail it. // ------------------------------------------------------------------------- /*if (EngineConstants.LOG_ENABLED==EngineConstants.TRUE) { _VerifyDurationType(eEffect, nEffectType); SetIsCurrentEffectValid(EngineConstants.FALSE); return EngineConstants.FALSE; }*/ // string sTypeName = Log_GetEffectNameById(nEffectType); #if DEBUG Log_Trace_Effects("effects_h.HandleApplyEffect", eEffect, "", gameObject); #endif //</Debug> // ------------------------------------------------------------------------- // Dead creatures no longer accept any other xEffect except for resurrection || death! // ------------------------------------------------------------------------- if (IsDead(gameObject) != EngineConstants.FALSE && (nEffectType != EngineConstants.EFFECT_TYPE_RESURRECTION && nEffectType != EngineConstants.EFFECT_TYPE_DEATH)) { #if DEBUG Log_Trace_Effects("effects_h.HandleApplyEffect", eEffect, "EngineConstants.EFFECT_REJECTED - target is dead", gameObject); #endif nReturnValue = EngineConstants.FALSE; } else { if (GetObjectType(gameObject) == EngineConstants.OBJECT_TYPE_CREATURE) { int nMessage = EngineConstants.UI_MESSAGE_IMMUNE; // ----------------------------------------------------------------- // Knockdown and stun end grab // ----------------------------------------------------------------- if (nEffectType == EngineConstants.EFFECT_TYPE_KNOCKDOWN || nEffectType == EngineConstants.EFFECT_TYPE_STUN || nEffectType == EngineConstants.EFFECT_TYPE_PARALYZE || nEffectType == EngineConstants.EFFECT_TYPE_SLIP) { List<xEffect> aGrab = GetEffects(gameObject, EngineConstants.EFFECT_TYPE_GRABBING, 0, gameObject); if (RemoveEffectArray(gameObject, aGrab) > 0) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "any grabbing xEffect removed by other effect!", gameObject); #endif nMessage = EngineConstants.UI_MESSAGE_GRAB_BROKEN; } else { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "conecasting xEffect removed by stun!", gameObject); #endif List<xEffect> aCast = GetEffects(gameObject, EngineConstants.EFFECT_TYPE_CONECASTING, 0, gameObject); RemoveEffectArray(gameObject, aCast); } } if (nEffectType == EngineConstants.EFFECT_TYPE_GRABBED || nEffectType == EngineConstants.EFFECT_TYPE_PARALYZE) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "conecasting xEffect removed by grab or paralyze!", gameObject); #endif List<xEffect> aCast = GetEffects(gameObject, EngineConstants.EFFECT_TYPE_CONECASTING, 0, gameObject); RemoveEffectArray(gameObject, aCast); } // ----------------------------------------------------------------- // Implementation for spell ward. // ----------------------------------------------------------------- if (GetAbilityType(nAbilityId) == EngineConstants.ABILITY_TYPE_SPELL) { if (GetHasEffects(gameObject, EngineConstants.EFFECT_TYPE_SPELL_WARD) != EngineConstants.FALSE) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "spell xEffect not applied, creature has EngineConstants.EFFECT_SPELL_WARD!", gameObject); #endif ApplyEffectVisualEffect(oCreator, gameObject, 1556, EngineConstants.EFFECT_DURATION_TYPE_INSTANT, 0.0f, nAbilityId); UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_SPELL_IMMUNITY); nReturnValue = EngineConstants.FALSE; } } if (nReturnValue == -1) { int nImmune = IsImmuneToEffectType(gameObject, nEffectType); if (nImmune > 0) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "effect not applied, creature immune!", gameObject); #endif if (nImmune == 1) { UI_DisplayMessage(gameObject, nMessage); } else if (nImmune == 3) { UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_RESISTED); } nReturnValue = EngineConstants.FALSE; } } } // --------------------------------------------------------------------- // Georg: Invalidate hostile effects per target // --------------------------------------------------------------------- if (nReturnValue != EngineConstants.FALSE) { if (IsEffectTypeHostile(nEffectType) != EngineConstants.FALSE) { if (IsHostileEffectAllowed(gameObject, oCreator, nAbilityId) == EngineConstants.FALSE) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "hostile xEffect NOT applied - not allowed on target", gameObject); #endif nReturnValue = EngineConstants.FALSE; } } } if (GetM2DAInt(EngineConstants.TABLE_EFFECTS, "SimpleEffect", nEffectType) != EngineConstants.FALSE) { nReturnValue = EngineConstants.TRUE; } if (nReturnValue == -1) { switch (nEffectType) { case EngineConstants.EFFECT_TYPE_NULL: case EngineConstants.EFFECT_TYPE_HEAVY_IMPACT: case EngineConstants.EFFECT_TYPE_LIFE_WARD: case EngineConstants.EFFECT_TYPE_PETRIFY: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_DAMAGE: { nReturnValue = Effects_HandleApplyEffectDamage(eEffect); break; } case EngineConstants.EFFECT_TYPE_DEATH: { nReturnValue = Effects_HandleApplyEffectDeath(eEffect); break; } case EngineConstants.EFFECT_TYPE_RESURRECTION: { nReturnValue = Effects_HandleApplyEffectResurrection(eEffect); break; } case EngineConstants.EFFECT_TYPE_MODIFYMANASTAMINA: { nReturnValue = Effects_HandleApplyEffectModifyManaStamina(eEffect); break; } case EngineConstants.EFFECT_TYPE_HEALHEALTH: { nReturnValue = Effects_HandleApplyEffectHeal(eEffect); break; } case EngineConstants.EFFECT_TYPE_ROOT: { nReturnValue = Effects_HandleApplyEffectRoot(eEffect); AI_Threat_ClearEnemiesThreatToMe(gameObject); break; } case EngineConstants.EFFECT_TYPE_KNOCKDOWN: { nReturnValue = Effects_HandleApplyEffectKnockdown(eEffect); break; } case EngineConstants.EFFECT_TYPE_MODIFYATTRIBUTE: { nReturnValue = Effects_HandleApplyEffectModifyAttribute(eEffect); break; } case EngineConstants.EFFECT_TYPE_UPKEEP: { nReturnValue = Effects_HandleApplyEffectUpkeep(eEffect); break; } case EngineConstants.EFFECT_TYPE_DOT: { nReturnValue = Effects_HandleApplyEffectDOT(eEffect); break; } case EngineConstants.EFFECT_TYPE_DAZE: { nReturnValue = Effects_HandleApplyEffectDaze(eEffect); break; } case EngineConstants.EFFECT_TYPE_DISEASE: { nReturnValue = Effects_HandleApplyEffectDisease(eEffect); break; } case EngineConstants.EFFECT_TYPE_DISPEL_MAGIC: { nReturnValue = Effects_HandleApplyEffectDispelMagic(eEffect); break; } case EngineConstants.EFFECT_TYPE_MODIFY_CRITCHANCE: { nReturnValue = Effects_HandleApplyEffectModifyCritChance(eEffect); break; } case EngineConstants.EFFECT_TYPE_DECREASE_PROPERTY: case EngineConstants.EFFECT_TYPE_MODIFY_PROPERTY: { nReturnValue = Effects_HandleApplyEffectModifyProperty(eEffect); break; } case EngineConstants.EFFECT_TYPE_AI_MODIFIER: { nReturnValue = Effects_HandleApplyEffectAIModifier(eEffect); break; } case EngineConstants.EFFECT_TYPE_ADDABILITY: { nReturnValue = Effects_HandleApplyEffectAddAbility(eEffect); break; } case EngineConstants.EFFECT_TYPE_CONECASTING: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_ROOTING: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_GRABBING: case EngineConstants.EFFECT_TYPE_GRABBED: case EngineConstants.EFFECT_TYPE_OVERWHELMED: case EngineConstants.EFFECT_TYPE_OVERWHELMING: /*intentional fallthrough*/ { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_REGENERATION: { nReturnValue = Effects_HandleApplyEffectRegeneration(eEffect); break; } case EngineConstants.EFFECT_TYPE_STUN: { nReturnValue = Effects_HandleApplyEffectStun(eEffect); break; } case EngineConstants.EFFECT_TYPE_CONFUSION: { nReturnValue = Effects_HandleApplyEffectConfusion(eEffect); break; } case EngineConstants.EFFECT_TYPE_CHARM: { nReturnValue = Effects_HandleApplyEffectCharm(eEffect); break; } case EngineConstants.EFFECT_TYPE_SLEEP: case EngineConstants.EFFECT_TYPE_SLEEP_PLOT: { nReturnValue = Effects_HandleApplyEffectSleep(eEffect); AI_Threat_ClearEnemiesThreatToMe(gameObject); break; } case EngineConstants.EFFECT_TYPE_STEALTH: { nReturnValue = Effects_HandleApplyEffectStealth(eEffect); break; } case EngineConstants.EFFECT_TYPE_TEST: // 11/15/07 { nReturnValue = Effects_HandleApplyEffectTest(eEffect); break; } case EngineConstants.EFFECT_TYPE_HEARTBEAT: { nReturnValue = Effects_HandleApplyEffectHeartbeat(eEffect); break; } case EngineConstants.EFFECT_TYPE_RECURRING_KNOCKDOWN: // 05/12/07 { nReturnValue = Effects_HandleApplyEffectRecurringKnockdown(eEffect); break; } case EngineConstants.EFFECT_TYPE_WALKING_BOMB: { nReturnValue = Effects_HandleApplyEffectWalkingBomb(eEffect); AI_Threat_ClearEnemiesThreatToMe(gameObject); break; } case EngineConstants.EFFECT_TYPE_SUMMON: { nReturnValue = Effects_HandleApplyEffectSummon(eEffect); break; } case EngineConstants.EFFECT_TYPE_SHAPECHANGE: { nReturnValue = Effects_HandleApplyEffectShapechange(eEffect); break; } case EngineConstants.EFFECT_TYPE_ENCHANTMENT: { nReturnValue = Effects_HandleApplyEffectEnchantment(eEffect); break; } case EngineConstants.EFFECT_TYPE_LOCK_INVENTORY: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_LOCK_QUICKBAR: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_LOCK_CHARACTER: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_FEIGN_DEATH: { nReturnValue = Effects_HandleApplyEffectFeignDeath(eEffect); break; } case EngineConstants.EFFECT_TYPE_SIMULATE_DEATH: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_FLANK_IMMUNITY: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_FEAR: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_MISDIRECTION_HEX: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_DEATH_HEX: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_CURSE_OF_MORTALITY: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_SLIP: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_SPELL_WARD: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_DAMAGE_WARD: { nReturnValue = EngineConstants.TRUE; AI_Threat_ClearEnemiesThreatToMe(gameObject); break; } case EngineConstants.EFFECT_TYPE_WYNNE_REMOVAL: { nReturnValue = EngineConstants.TRUE; break; } case EngineConstants.EFFECT_TYPE_SWARM: { nReturnValue = Effects_HandleApplyEffectSwarm(eEffect); break; } case EngineConstants.EFFECT_TYPE_MABARI_DOMINANCE: { nReturnValue = Effects_HandleApplyEffectMabariDominance(eEffect); break; } /*switch*/ } /* if nReturnValue == -1 */ } } /*if*/ // ------------------------------------------------------------------------- // Notify if we forgot to handle an effect // ------------------------------------------------------------------------- if (nReturnValue == -1) { #if DEBUG Warning("EngineConstants.EFFECT_NOT_HANDLED! " + Log_GetEffectNameById(nEffectType) + ". + Contact Georg"); Log_Trace_Scripting_Error("effects_h.HandleApplyEffect", "EngineConstants.EFFECT_NOT_HANDLED! " + Log_GetEffectNameById(nEffectType), gameObject); #endif nReturnValue = EngineConstants.FALSE; } // ------------------------------------------------------------------------- // This notifies the engine on whether or not to go ahead with applying the // effect. If this is false, the engine will discard the effect, firing a // RemoveEffect xEvent to rules_core, which will message it to Effects_HandleRemoveEffect // below // ------------------------------------------------------------------------- if (nReturnValue == 0) { #if DEBUG Log_Trace_Effects("effects_h.HandleApply", eEffect, "effect found not valid (EngineConstants.FALSE reported back)", gameObject); #endif } if (nReturnValue != EngineConstants.FALSE) { // --------------------------------------------------------------------- // Certain effects kill stealth. // --------------------------------------------------------------------- if (GetM2DAInt(EngineConstants.TABLE_EFFECTS, "bDropStealth", nEffectType) != EngineConstants.FALSE) { SignalEventDropStealth(gameObject); } } SetIsCurrentEffectValid(ev, nReturnValue); return nReturnValue; }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_UNLOCK_FAILED placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleUnlockFailed(xEvent ev) { // play unlock failed sound string sSound = GetM2DAString(EngineConstants.TABLE_PLACEABLE_TYPES, "PickLockFailure", GetAppearanceType(gameObject)); PlaySound(gameObject, sSound); /* GameObject oPlc = gameObject; if (!IsPlot(oPlc)) { // Try bashing it open instead. GameObject oUser = GetEventObjectRef(ref ev, 0); WR_AddCommand(oUser, CommandAttack(oPlc)); } */ }
//------------------------------------------------------------------------------ public void ORZ_BrankaCaridin_HandleEventRockFall(xEvent evEvent) { int nLoopNum = GetEventIntegerRef(ref evEvent, 0); int nLoopGroup = GetEventIntegerRef(ref evEvent, 1); xEffect effEruption = EffectVisualEffect(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_ERUPTION_VFX); GameObject oBranka = GetObjectByTag(EngineConstants.ORZ_CR_BRANKA); List<GameObject> arTargets = GetNearestObjectByTag(oBranka, EngineConstants.ORZ_ANVIL_WP_LAVA_QUAKE_PREFIX + ToString(nLoopGroup), EngineConstants.OBJECT_TYPE_WAYPOINT, EngineConstants.ORZ_ANVIL_LAVA_QUAKE_MAX_ERUPTIONS); int size, i; Vector3 vTarget, vSource; xEvent evBrankaImpact; GameObject oTarget, oPrj; if (IsDeadOrDying(oBranka) == EngineConstants.FALSE && GetCombatState(oBranka) != EngineConstants.FALSE) { // loop through the waypoint targets size = GetArraySize(arTargets); for (i = 0; i < size; i++) { oTarget = arTargets[i]; vTarget = GetPosition(oTarget); // the projectile is thick, so account for it's radius for // when it collides with the ground. vTarget.z = vTarget.z + 0.3f; // The source of the projectile is high above it, so modify // the z-value vSource = Vector(vTarget.x, vTarget.y, vTarget.z + 100 + Engine_Random(50)); // The result for this is ALWAYS sent to Branka, she handles it // in her character script. oPrj = FireProjectile(EngineConstants.ORZ_ANVIL_ROCK_FALL_PROJECTILE_ID, vSource, vTarget, 0, EngineConstants.FALSE, oBranka); evBrankaImpact = Event(EngineConstants.ORZ_ANVIL_EVENT_ROCK_FALL_IMPACT); SetEventVectorRef(ref evBrankaImpact, 0, GetLocation(oTarget)); SetProjectileImpactEvent(oPrj, evBrankaImpact); } // Apply an earthquake VFX and Screen-Shake ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, EffectVisualEffect(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_EARTHQUAKE_VFX), oBranka, EngineConstants.ORZ_ANVIL_ROCK_FALL_GROUP_DELAY); ApplyEffectOnParty(EngineConstants.EFFECT_DURATION_TYPE_TEMPORARY, EffectScreenShake(EngineConstants.ORZ_ANVIL_LAVA_QUAKE_SCREENSHAKE_ID), 3.0f); // Send the xEvent back to the area SetEventIntegerRef(ref evEvent, 0, (nLoopNum + 1)); SetEventIntegerRef(ref evEvent, 1, ((nLoopGroup + 1) % EngineConstants.ORZ_ANVIL_LAVA_QUAKE_NUM_GROUPS)); DelayEvent(EngineConstants.ORZ_ANVIL_ROCK_FALL_GROUP_DELAY, gameObject, evEvent); } }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_UNLOCKED placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleUnlocked(xEvent ev) { // play unlock success sound string sSound = GetM2DAString(EngineConstants.TABLE_PLACEABLE_TYPES, "PickLockSuccess", GetAppearanceType(gameObject)); PlaySound(gameObject, sSound); // Automatically open doors/containers when they are unlocked. GameObject oUser = GetEventObjectRef(ref ev, 0); string sStateController = GetPlaceableStateCntTable(gameObject); if (sStateController == EngineConstants.PLC_STATE_CONTROLLER_CONTAINER) { AddCommand(oUser, CommandUseObject(gameObject, EngineConstants.PLACEABLE_ACTION_OPEN_INVENTORY)); } /* else if (sStateController == EngineConstants.PLC_STATE_CONTROLLER_DOOR) { AddCommand(oUser, CommandUseObject(gameObject, EngineConstants.PLACEABLE_ACTION_OPEN)); } */ }
//------------------------------------------------------------------------------ public void ORZ_BrankaCaridin_HandleEventBrankaIllusionDamaged(xEvent evEvent) { int nCounter = GetLocalInt(gameObject, EngineConstants.CREATURE_COUNTER_1); GameObject oBranka = GetObjectByTag(EngineConstants.ORZ_CR_BRANKA); // Apply ghost vfx if (nCounter == 0) ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_PERMANENT, EffectVisualEffect(3007), gameObject, 0.0f, oBranka); // Remove Copy else if (nCounter >= 2) ORZ_BrankaCaridin_BrankaIllusionRemoveCopy(gameObject); SetLocalInt(gameObject, EngineConstants.CREATURE_COUNTER_1, (nCounter + 1)); }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_COMMAND_COMPLETE placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleCastAt(xEvent ev) { }
public void HandleEvent(xEvent ev) { //xEvent ev = engine.GetCurrentEvent(); int nEventType = engine.GetEventTypeRef(ref ev); // ------------------------------------------------------------------------- // Generic xEvent message // ------------------------------------------------------------------------- #if DEBUG engine.Log_Events("", ev); #endif switch (nEventType) { // GM - Temp handling of RUBBER BAND event // -------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_RUBBER_BAND - Creature chased someone too far // -------------------------------------------------------------------- case 87: { /* ClearAllCommands(gameObject); GameObject oArea = engine.GetArea(gameObject); Vector3 vPos; vPos.x = engine.GetLocalFloat(gameObject, "RUBBER_HOME_LOCATION_X"); vPos.y = engine.GetLocalFloat(gameObject, "RUBBER_HOME_LOCATION_Y"); vPos.z = engine.GetLocalFloat(gameObject, "RUBBER_HOME_LOCATION_Z"); Vector3 lLoc = Location(oArea, vPos, 0.0f); xCommand cMove = engine.CommandMoveToLocation(lLoc); engine.WR_AddCommand(gameObject, cMove); DEBUG_PrintToScreen(engine.GetTag(gameObject) + "Reached Rubber Band Limit"); */ break; } // GM - Temp handling of GIVE UP event // -------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_GIVE_UP - Creature chased someone for too long // -------------------------------------------------------------------- case 88: { /* ClearAllCommands(gameObject); xCommand cWait = engine.CommandWait(2.0f); engine.WR_AddCommand(gameObject, cWait); DEBUG_PrintToScreen(engine.GetTag(gameObject) + " Giving Up"); */ break; } // -------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_APPLY_EFFECT - Effect being applied // -------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_APPLY_EFFECT: { engine.Effects_HandleApplyEffect(ev);//DHK break; } case 90210: { engine.HandleEventRef(ref ev, EngineConstants.RESOURCE_SCRIPT_ABILITY_CORE); break; } // -------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_APPLY_EFFECT - Effect being unapplied // -------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_REMOVE_EFFECT: { engine.Effects_HandleRemoveEffect(); break; } // -------------------------------------------------------------------- // EngineConstants.COMMAND_PENDING - Deal with pending commands issued either by the AI // or by player input // Params: // obj(0) - engine.Command Owner // obj(1) - engine.Command Target // obj(2) - varies by command. // int(0) - The xCommand id (EngineConstants.COMMAND_TYPE_* constant) // int(1) - The xCommand subtype: // EngineConstants.COMMAND_TYPE_ATTACK - # of attacks // EngineConstants.COMMAND_TYPE_ABILITY - EngineConstants.ABILITY_TYPE constant * // // Note: Ranged Attacks always send one attack, never two. // // -------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_COMMAND_PENDING: { GameObject oCommandOwner = engine.GetEventObjectRef(ref ev, 0); GameObject oTarget = engine.GetEventObjectRef(ref ev, 1); int nCommandId = engine.GetEventIntegerRef(ref ev, 0); int nCommandSubType = engine.GetEventIntegerRef(ref ev, 1); // ----------------------------------------------------------------- // Validate the xEvent (target ok? user alife, etc.) // ----------------------------------------------------------------- if (engine.Events_ValidateCommandPending(oCommandOwner, oTarget, nCommandId, nCommandSubType) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Discarding EngineConstants.EVENT_TYPE_COMMAND_PENDING (" + engine.ToString(nCommandId) + ")"); #endif return; } // ----------------------------------------------------------------- // Melee Attack... // ----------------------------------------------------------------- if (nCommandId == EngineConstants.COMMAND_TYPE_ATTACK) { if (engine.GetCombatantType(oTarget) == EngineConstants.CREATURE_TYPE_NON_COMBATANT) { engine.Warning("Noncombatant Creature " + engine.ToString(oTarget) + " is target of an attack command! Pause and get Georg or Yaron"); } // Flagging party as clear to attack (if controlled follower) if (engine.IsControlled(gameObject) != EngineConstants.FALSE && engine.IsObjectValid(oTarget) != EngineConstants.FALSE && engine.IsObjectHostile(gameObject, oTarget) != EngineConstants.FALSE) { engine.AI_SetPartyAllowedToAttack(EngineConstants.TRUE); #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_COMMAND_PENDING", "Controlled follower attacking - clearing party to attack"); #endif } int nCommandResult = engine.Combat_HandleCommandAttack(oCommandOwner, oTarget, nCommandSubType); // ------------------------------------------------------------- // Trigger a battle cry // ------------------------------------------------------------- if (nCommandResult == EngineConstants.COMMAND_RESULT_SUCCESS) { engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_COMBAT_BATTLECRY); } // ------------------------------------------------------------- // Send the xCommand result to the engine, this starts the // xCommand execution. // ------------------------------------------------------------- engine.SetCommandResult(oCommandOwner, nCommandResult); } // ----------------------------------------------------------------- // Abilities, Spells // ----------------------------------------------------------------- else if (nCommandId == EngineConstants.COMMAND_TYPE_USE_ABILITY) { // Flagging party as clear to attack (if controlled follower) if (engine.IsControlled(gameObject) != EngineConstants.FALSE && engine.IsObjectValid(oTarget) != EngineConstants.FALSE && engine.IsObjectHostile(gameObject, oTarget) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_COMMAND_PENDING", "Controlled follower using hostile ability - clearing party to attack"); #endif engine.AI_SetPartyAllowedToAttack(EngineConstants.TRUE); } // ------------------------------------------------------------- // Redirect into ability_core // ------------------------------------------------------------- engine.HandleEventRef(ref ev, EngineConstants.RESOURCE_SCRIPT_ABILITY_CORE); } else { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_GENERAL, "rules_core.EngineConstants.EVENT_TYPE_COMMAND_PENDING ", "Unknown EngineConstants.COMMAND_TYPE " + engine.IntToString(nCommandId) + " received, ignoring", oTarget); #endif } break; } // --------------------------------------------------------------------- // Georg: relevant eclipse engine code /* pAttackerOnHitEvent->SetCreator(nAttackerId); pAttackerOnHitEvent->SetObjectId(0, nAttackerId); pAttackerOnHitEvent->SetInteger(0, pAttackerItem->engine.GetOnHitEffectId()); pAttackerOnHitEvent->SetInteger(1, pAttackerItem->engine.GetOnHitPower()); pAttackerOnHitEvent->SetObjectId(1, pAttackerItem->engine.GetId()); pAttackerOnHitEvent->SetTarget(a_pEventData->m_nTargetId); */ // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_ITEM_ONHIT: { // ----------------------------------------------------------------- // This xEvent is only ever processed in EngineConstants.GM_COMBAT // note: That means that NPCs fighting NPCs while not visible to // the player (shouldn't ever happen anyway) will not trigger // OnHit item abilities. // ----------------------------------------------------------------- if (engine.GetGameMode() == EngineConstants.GM_COMBAT) { int nOnHitEffectId = engine.GetEventIntegerRef(ref ev, 0); int nForceProc = engine.GetEventIntegerRef(ref ev, 2); // ----------------------------------------------------------------- // First determine proc chance. If no proc, no point in wasting // cpu time on the rest // ----------------------------------------------------------------- float fProc = engine.GetM2DAFloat(EngineConstants.TABLE_ITEMPRPS, "ProcChance", nOnHitEffectId); if (engine.RandomFloat() < fProc || nForceProc > 0) { GameObject oAttacker = engine.GetEventCreatorRef(ref ev); // check to see if the character is in a shapeshifted form // this prevents a rat from having a huge stack of damage floaties from equipment if (engine.IsShapeShifted(oAttacker) == EngineConstants.FALSE) { GameObject oTarget = engine.GetEventTargetRef(ref ev); GameObject oItem = engine.GetEventObjectRef(ref ev, 1); int nPower = 1; if (engine.IsObjectValid(oItem) != EngineConstants.FALSE) { nPower = Convert.ToInt32(engine.GetItemPropertyPower(oItem, nOnHitEffectId, EngineConstants.TRUE)); } // ------------------------------------------------------------- // No care about dead targets or non creatures // ------------------------------------------------------------- if (engine.GetObjectType(oTarget) == EngineConstants.OBJECT_TYPE_CREATURE && engine.IsDeadOrDying(oTarget) == EngineConstants.FALSE) { engine.ItemProp_DoEffect(oAttacker, oTarget, nOnHitEffectId, nPower); } } } } break; } case EngineConstants.EVENT_TYPE_DAMAGED: { // This GameObject lost 1 hit point or more if (engine.IsDeadOrDying(gameObject) != EngineConstants.FALSE) { return; } int bSound = EngineConstants.TRUE; GameObject oDamager = engine.GetEventCreatorRef(ref ev); float fDamage = engine.GetEventFloatRef(ref ev, 0); int nDamageType = engine.GetEventIntegerRef(ref ev, 0); int nAbility = engine.GetEventIntegerRef(ref ev, 1); if (engine.IsFollower(gameObject) == EngineConstants.FALSE) engine.AI_Threat_UpdateDamage(gameObject, oDamager, fDamage); if (engine.IsStealthy(gameObject) != EngineConstants.FALSE && nDamageType != EngineConstants.DAMAGE_TYPE_PHYSICAL) { // stealth 3 and 4 have a chance to not drop on non-physical damage int nLevel = engine.GetLevel(gameObject); float fChance = -1.0f; if (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_STEALTH_4) != EngineConstants.FALSE) { fChance = nLevel * 0.02f; } else if (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_STEALTH_3) != EngineConstants.FALSE) { fChance = nLevel * 0.01f; } fChance = engine.MinF(fChance, 0.8f); if (engine.RandomFloat() > fChance) { engine.DropStealth(gameObject); } } // If not a follower and damaged outside of combat and does not perceive the damager // then try to move to damager. // the following check needs to be outside of gamemode=combat check because it can happen when the gamemode is not combat // for example: around a corner where no one perceives each other yet if (engine.GetObjectType(oDamager) == EngineConstants.OBJECT_TYPE_CREATURE && engine.GetCombatState(gameObject) == EngineConstants.FALSE && engine.IsFollower(gameObject) == EngineConstants.FALSE && engine.IsPerceiving(gameObject, oDamager) == EngineConstants.FALSE) { Vector3 lLoc = engine.GetLocation(oDamager); engine.WR_ClearAllCommands(gameObject, EngineConstants.TRUE); xCommand cMove = engine.CommandMoveToLocation(lLoc, EngineConstants.TRUE); engine.WR_AddCommand(gameObject, cMove); } // ----------------------------------------------------------------- // Attack Interruption // This should only ever happen in combat. // @author georg // ----------------------------------------------------------------- if (engine.GetGameMode() == EngineConstants.GM_COMBAT) { // ------------------------------------------------------------- // Only significant damage disrupts // ------------------------------------------------------------- if (nDamageType == EngineConstants.DAMAGE_TYPE_PHYSICAL) { xCommand cmd = engine.GetCurrentCommand(gameObject); int nCmdType = engine.GetCommandType(cmd); // --------------------------------------------------------- // We only interrupt attack commands at this point // --------------------------------------------------------- if (nCmdType == EngineConstants.COMMAND_TYPE_ATTACK) { //--------------------------------------------------------- // Damage needs to exceed dexterity modifier/3 to interrupt //---------------------------------------------------------- float fModifier = engine.GetAttributeModifier(gameObject, EngineConstants.ATTRIBUTE_DEX) * (1.0f / 3.0f); if (fDamage > fModifier) { // ------------------------------------------------- // Melee archers ignore interruptions // ------------------------------------------------- if (engine.HasAbility(gameObject, EngineConstants.ABILITY_TALENT_MELEE_ARCHER) == EngineConstants.FALSE) { if (engine.IsUsingMeleeWeapon(oDamager, null) != EngineConstants.FALSE) { if (engine.IsUsingRangedWeapon(gameObject, null, EngineConstants.TRUE) != EngineConstants.FALSE) { engine.UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_INTERRUPTED); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_COMBAT, "rules_core.OnDamage", "Ranged attack interrupted by damage"); #endif engine.WR_ClearAllCommands(gameObject, EngineConstants.TRUE); } } } } } // --------------------------------------------------------- // Experimental: Taking any damage > 1 causes spell interruption // --------------------------------------------------------- else if (nCmdType == EngineConstants.COMMAND_TYPE_USE_ABILITY) { int nAbi = engine.GetCommandIntRef(ref cmd, 0); // Only abilities with speed >0 can be interrupted. if (engine.CanInterruptSpell(nAbi) != EngineConstants.FALSE) { int nCombatTrainingRank = 0; int nModifier = 0; float fThres = 0.0f; // ----------------------------------------------------- if (engine.IsPartyMember(gameObject) == EngineConstants.FALSE) { nCombatTrainingRank = engine.GetM2DAInt(engine.Diff_GetAutoScaleTable(), "nCombatTraining", engine.GetCreatureRank(gameObject)); nModifier = engine.GetLevel(gameObject); } else { nCombatTrainingRank = (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_COMBAT_TRAINING_1)) + (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_COMBAT_TRAINING_2)) + (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_COMBAT_TRAINING_3)) + (engine.HasAbility(gameObject, EngineConstants.ABILITY_SKILL_COMBAT_TRAINING_4)); nModifier = 5 + engine.GetLevel(gameObject) / 2; } fThres = (nCombatTrainingRank * 10.0f) + nModifier; // ----------------------------------------------------- // Damage needs to exceed a certain threshold before it // can interrupt. Otherwise playing mages gets very // frustrating. // ----------------------------------------------------- if (fDamage > fThres) { // --------------------------------------------- // Since EngineConstants.COMMAND_USEABILITY can be in a movement // subaction, filter additionally for conjure // phase. // --------------------------------------------- if (engine.IsConjuring(gameObject) != EngineConstants.FALSE) { engine.UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_INTERRUPTED); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_COMBAT, "rules_core.OnDamage", "Spell interrupted by damage"); #endif engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_SPELL_INTERRUPTED); bSound = EngineConstants.FALSE; engine.WR_ClearAllCommands(gameObject, EngineConstants.TRUE); } } else { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_COMBAT, "rules_core.OnDamage", "Spell not interrupted, dmg " + engine.ToString(fDamage) + " below threshold: " + engine.ToString(fThres)); #endif } } } } if (fDamage >= EngineConstants.SOUND_THRESH_DAMAGE_AMOUNT && bSound != EngineConstants.FALSE) { engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_GOT_DAMAGED, oDamager); } // ------------------------------------------------------------- // engine.Handle various effects // ------------------------------------------------------------- engine.Ability_HandleOnDamageAbilities(gameObject, oDamager, fDamage, nDamageType, nAbility); } break; } // --------------------------------------------------------------------- // Object is spawned. Fires once per object // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_SPAWN: { // The GameObject spawned into the game. int nSpawned = engine.GetLocalInt(gameObject, EngineConstants.CREATURE_SPAWNED); if (nSpawned == 1) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, "rules_core.EngineConstants.EVENT_TYPE_SPAWN", "creature spawned before - NOT triggering spawn routine again."); #endif } else engine.SetLocalInt(gameObject, EngineConstants.CREATURE_SPAWNED, 1); // Enable/disable lookat engine.SetLookAtEnabled(gameObject, engine.GetLocalInt(gameObject, EngineConstants.LOOKAT_DISABLED) != EngineConstants.FALSE ? EngineConstants.TRUE : EngineConstants.FALSE); break; } // --------------------------------------------------------------------- // An attack has impacted the target. This can be melee (sword hit), // ranged (arrow hit) or spell (fireball explodes). Used for applying damage // and handling abilities that need to do something on hit (Berserk etc'). // // Here we do the actual damage for successful attacks. The damage is // being sent by this event, but it has been passed through from // scripting in EngineConstants.COMMAND_PENDING // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_ATTACK_IMPACT: { GameObject oAttacker = engine.GetEventObjectRef(ref ev, 0); GameObject oTarget = engine.GetEventObjectRef(ref ev, 1); int nHitResult = engine.GetEventIntegerRef(ref ev, 0); int nEffectId = engine.GetEventIntegerRef(ref ev, 1); xEffect eImpactEffect = engine.GetAttackImpactDamageEffect(oAttacker, nEffectId); engine.UI_DisplayMessage(oAttacker, EngineConstants.UI_DEBUG_EVENT_IMPACT_ATTACK); // ----------------------------------------------------------------- // //Track any combat impact by the player. // This is potentially expensive, so it's disabled until georg // has evaluated if the server can handle it. // ----------------------------------------------------------------- if (engine.IsFollower(oAttacker) != EngineConstants.FALSE) { /*if (TRACKING_TRACK_COMBAT_IMPACT) { #if SKYNET //TrackCombatEvent(nEventType, oAttacker, oTarget, nHitResult, 0); #endif }*/ } // ----------------------------------------------------------------- // Check for dead attacker, etc, etc, to invalidate events that // should no longer be processed. // ----------------------------------------------------------------- if (engine.Events_FilterAttackImpactEvent(oAttacker, oTarget, nHitResult) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Discarding EngineConstants.EVENT_TYPE_ATTACK_IMPACT", oTarget); #endif return; } // ----------------------------------------------------------------- // Signal an OnAttacked result to the attacked creature // ----------------------------------------------------------------- engine.SendEventOnAttacked(oTarget, oAttacker); engine.Combat_HandleAttackImpact(oAttacker, oTarget, nHitResult, eImpactEffect); break; } // --------------------------------------------------------------------- // Equip Event // EventCreator - The creature owning the item // obj(0) - The item. // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_UNEQUIP: case EngineConstants.EVENT_TYPE_EQUIP: { GameObject oItem = engine.GetEventObjectRef(ref ev, 0); GameObject oUser = engine.GetEventCreatorRef(ref ev); int nSlot = engine.GetEventIntegerRef(ref ev, 0); if (engine.IsPartyMember(oUser) != EngineConstants.FALSE) { engine.RecalculateDisplayDamage(gameObject); } break; } case EngineConstants.EVENT_TYPE_CAST_AT: { Engine.EventOnCastAtParamStruct stEvent = engine.GetEventOnCastAtParams(ev); // Updating ability-use threat. This value applies threat when specific abilities are // used regardless of who the target is. For example: Berserk, buffing self or allies etc' //AI_Threat_UpdateAbilityUsed(stEvent.oCaster, stEvent.nAbility); if (stEvent.bHostile != EngineConstants.FALSE) { // ----------------------------------------------------------------- // Core engine functionality, do not mess with these lines // Adding oAttacker to oTarget's perception list and vice versa // ----------------------------------------------------------------- if (engine.IsPerceiving(gameObject, stEvent.oCaster) == EngineConstants.FALSE) { engine.WR_TriggerPerception(gameObject, stEvent.oCaster); engine.WR_TriggerPerception(stEvent.oCaster, gameObject); } // IMPORTANT: it is assumed this works for talents impact as well! // This threat is generated for hostile ability effects like paralyze or disease. if (engine.IsFollower(gameObject) == EngineConstants.FALSE) engine.AI_Threat_UpdateAbilityImpact(gameObject, stEvent.oCaster, stEvent.nAbility); } //else // non-hostile //{ // if(stEvent.fParam1 > 0.0f) // for now - this is used ONLY for damage healed // engine.AI_Threat_UpdateHealing(gameObject, stEvent.oCaster, stEvent.fParam1); //} break; } case EngineConstants.EVENT_TYPE_ATTACKED: { GameObject oAttacker = engine.GetEventObjectRef(ref ev, 0); // ----------------------------------------------------------------- // Core engine functionality, do not mess with these lines // Adding oAttacker to oTarget's perception list and vice versa // ----------------------------------------------------------------- if (engine.IsStealthy(gameObject) == EngineConstants.FALSE) { engine.WR_TriggerPerception(gameObject, oAttacker); engine.WR_TriggerPerception(oAttacker, gameObject); } // ----------------------------------------------------------------- // Brute force fix for any lingering game mode issues: // If we are attacked by a hostile GameObject in explore mode // and we are a follower, we force the game into combat mode. // ----------------------------------------------------------------- if (engine.GetGameMode() == EngineConstants.GM_EXPLORE) { if (engine.IsFollower(gameObject) != EngineConstants.FALSE && engine.IsObjectHostile(gameObject, oAttacker) != EngineConstants.FALSE && engine.GetCombatState(gameObject) == EngineConstants.FALSE) { if (engine.GetObjectType(oAttacker) == EngineConstants.OBJECT_TYPE_CREATURE && engine.IsPerceiving(gameObject, oAttacker) != EngineConstants.FALSE) engine.WR_SetGameMode(EngineConstants.GM_COMBAT); } } if (engine.IsFollower(gameObject) == EngineConstants.FALSE) engine.AI_Threat_UpdateEnemyAttacked(gameObject, oAttacker); xCommand cCurrent = engine.GetCurrentCommand(gameObject); // Disable stationary state (only if 'soft' state) // If a creature is attacked we don't want him anymore to stand and wait for enemy to be in range - // at this stange we'll allow him to chase enemies if (engine.GetLocalInt(gameObject, EngineConstants.AI_FLAG_STATIONARY) == EngineConstants.AI_STATIONARY_STATE_SOFT) engine.SetLocalInt(gameObject, EngineConstants.AI_FLAG_STATIONARY, EngineConstants.AI_STATIONARY_STATE_DISABLED); // A follower will be clear to attack enemies back once attacked himself (or once another follower was attacked) // (or when the controlled follower attacks - handles elsewhere) if (engine.IsFollower(gameObject) != EngineConstants.FALSE) engine.AI_SetPartyAllowedToAttack(EngineConstants.TRUE); // For ANY party member: // If in combat - run DetermineCombatRound_Partial if I'm doing nothing // This is done in order to have the player attack back someone who attack him if (engine.IsFollower(gameObject) != EngineConstants.FALSE && engine.GetCombatState(gameObject) != EngineConstants.FALSE && engine.GetCommandType(cCurrent) == EngineConstants.COMMAND_TYPE_INVALID) { if (engine.GetLocalInt(gameObject, EngineConstants.AI_CUSTOM_AI_ACTIVE) != EngineConstants.FALSE) // custom AI active { #if DEBUG engine.Log_Trace_AI("rules_core", "Executing CUSTOM AI"); #endif engine.SendEventHandleCustomAI(gameObject, oAttacker, -1, EngineConstants.COMMAND_RESULT_SUCCESS, -1); // } else { #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_ATTACKED", "calling DetermineCombatRound from the EngineConstants.ATTACKED event"); #endif engine.AI_DetermineCombatRound(oAttacker, -1, EngineConstants.COMMAND_RESULT_SUCCESS, -1); } } break; } // --------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_COMMAND_COMPLETE: // Called after a xCommand has finished executing. // // Params: // int(0) - Type of the last xCommand (e.g. EngineConstants.COMMAND_TYPE_ATTACKED) // int(1) - The status of the execution (EngineConstants.COMMAND_SUCCESSFUL, etc) // obj(0) - The target that xCommand was applied to // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_COMMAND_COMPLETE: { int nLastCommandType = engine.GetEventIntegerRef(ref ev, 0); int nCommandStatus = engine.GetEventIntegerRef(ref ev, 1); int nLastSubCommand = engine.GetEventIntegerRef(ref ev, 2); GameObject oLastTarget = null; GameObject oBlockingObject = engine.GetEventObjectRef(ref ev, 2); if (nLastCommandType == 0) { #if DEBUG engine.Log_Trace_Scripting_Error("rules_core", "Invalid xCommand complete received from engine. Contact Yaron"); #endif return; } if (nLastCommandType == EngineConstants.COMMAND_TYPE_USE_ABILITY) { engine.EnableWeaponTrail(gameObject, EngineConstants.FALSE); } if (engine.IsDisabled() != EngineConstants.FALSE || engine.IsDead() != EngineConstants.FALSE || engine.IsDying() != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), " discardng EngineConstants.EVENT_TYPE_COMMAND_COMPLETE (disabled, dead, or dying)"); #endif return; } // If this GameObject has a roam distance defined check if we // are close enough to the roam point to remove the speed // up and clear this creature's perception list. float fRoamDistance = engine.GetLocalFloat(gameObject, "ROAM_DISTANCE"); if (fRoamDistance > 25.0f) { if (nLastCommandType == EngineConstants.COMMAND_TYPE_MOVE_TO_LOCATION) { if (engine.GetHasEffects(gameObject, EngineConstants.EFFECT_TYPE_MOVEMENT_RATE, 0) != EngineConstants.FALSE) { if (engine.GetDistanceBetweenLocations(engine.GetRoamLocation(gameObject), engine.GetLocation(gameObject)) < 3.0f) { //DisplayFloatyMessage(gameObject,"BACK HOME!YAY!"); engine.RemoveEffectsByParameters(gameObject, EngineConstants.EFFECT_TYPE_MOVEMENT_RATE, 0, gameObject); engine.SetCombatState(gameObject, EngineConstants.FALSE); engine.ClearPerceptionList(gameObject); return; } } } } engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_COMMAND_COMPLETE); // In case something interactive (e.g. a door) was blocking the path // for the command, a solution is found here and immediately queued up. // After completing this intermediate action, the AI can resume normal execution. if (nCommandStatus == EngineConstants.COMMAND_FAILED_PATH_ACTION_REQUIRED) { int bAllowPathAction = (engine.IsControlled(gameObject) != EngineConstants.FALSE || engine.IsFollower(gameObject) == EngineConstants.FALSE) ? EngineConstants.TRUE : EngineConstants.FALSE; if (bAllowPathAction != EngineConstants.FALSE && engine.GetLocalInt(gameObject, EngineConstants.AI_DISABLE_PATH_BLOCKED_ACTION) == EngineConstants.FALSE) { if (engine.AI_DeterminePathBlockedAction(oBlockingObject) != EngineConstants.FALSE) return; } else { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_AI, engine.GetCurrentScriptName(), "Not handling Path-blocked xEvent (follower or has flag to disable this AI)"); #endif } } // Determine what to do for next round. // Behaviour depends on GameObject type and can execute outside combat. // For party members this should run every time a xCommand ends. // For normal creatures this should run only during combat. if (engine.IsFollower(gameObject) != EngineConstants.FALSE || (engine.IsFollower(gameObject) == EngineConstants.FALSE && engine.GetCombatState(gameObject) != EngineConstants.FALSE)) { if (nLastCommandType == EngineConstants.COMMAND_TYPE_ATTACK || nLastCommandType == EngineConstants.COMMAND_TYPE_USE_ABILITY) oLastTarget = engine.GetEventObjectRef(ref ev, 1); #if DEBUG if (engine.GetCreatureRank(gameObject) == EngineConstants.CREATURE_RANK_INVALID) engine.Log_Trace_Scripting_Error(engine.GetCurrentScriptName(), engine.ToString(gameObject) + " has no RANK"); #endif if (engine.GetLocalInt(gameObject, EngineConstants.AI_CUSTOM_AI_ACTIVE) != EngineConstants.FALSE) // custom AI active { #if DEBUG engine.Log_Trace_AI("rules_core", "Executing CUSTOM AI"); #endif engine.SendEventHandleCustomAI(gameObject, oLastTarget, nLastCommandType, nCommandStatus, nLastSubCommand); } else { engine.AI_DetermineCombatRound(oLastTarget, nLastCommandType, nCommandStatus, nLastSubCommand); break; } } // Ambient behaviour engine.Ambient_CommandComplete(nLastCommandType, nCommandStatus); // Adding this so people can have a SAFE substitute for command_complete when nothing else works if (engine.GetCombatState(gameObject) == EngineConstants.FALSE && engine.GetLocalInt(gameObject, EngineConstants.AI_CUSTOM_AI_ACTIVE) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace_AI("rules_core", "Executing CUSTOM COMMAND COMPLETE"); #endif xEvent evCustomCommandComplete = engine.Event(EngineConstants.EVENT_TYPE_CUSTOM_COMMAND_COMPLETE); engine.SetEventIntegerRef(ref evCustomCommandComplete, 0, nLastCommandType); engine.SetEventIntegerRef(ref evCustomCommandComplete, 1, nCommandStatus); engine.SetEventIntegerRef(ref evCustomCommandComplete, 2, nLastSubCommand); engine.SetEventObjectRef(ref evCustomCommandComplete, 2, oBlockingObject); engine.SignalEvent(gameObject, evCustomCommandComplete); } // handle creatures that should run away from hostiles (for example: city elf servant escorting the player) if (engine.GetPackageAI(gameObject) == 10130) // coward package engine.AI_HandleCowardFollower(); break; } case EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR: { GameObject oAppear = engine.GetEventObjectRef(ref ev, 0); int nHostile = engine.GetEventIntegerRef(ref ev, 0); // if hostile or not (EngineConstants.TRUE/EngineConstants.FALSE) int bStealthed = engine.GetEventIntegerRef(ref ev, 1); // if stealthed or not (EngineConstants.TRUE/EngineConstants.FALSE) int nHostilityChanged = engine.GetEventIntegerRef(ref ev, 2); // if the creature was already perceived but just changed hostility (EngineConstants.TRUE/EngineConstants.FALSE) int nSize; int i; GameObject oAlly; float fCombatDelay; // before starting combat; int nRand; // If it's a hostile creature lying on the ground and it perceives a party member // then it spawn as non-hostile. Need to turn him hostile now if (engine.GetLocalInt(gameObject, EngineConstants.SPAWN_HOSTILE_LYING_ON_GROUND) == 1 && engine.GetGroupId(gameObject) == EngineConstants.GROUP_HOSTILE_ON_GROUND) { if (engine.GetGroupId(oAppear) == EngineConstants.GROUP_PC) { engine.UT_CombatStart(gameObject, oAppear); engine.SetLocalInt(gameObject, EngineConstants.SPAWN_HOSTILE_LYING_ON_GROUND, 0); // disable it for next perception } } //if it is a creature that has its GO_HOSTILE_ON_PERCEIVE_PC variable set - go hostile and attack if (engine.GetLocalInt(gameObject, EngineConstants.GO_HOSTILE_ON_PERCEIVE_PC) == 1) { if (engine.GetGroupId(oAppear) == EngineConstants.GROUP_PC) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PERCEPTION, "rules_core", "PC Group Perceived - Changing from Neutral to Hostile"); #endif //Do Once Only engine.SetLocalInt(gameObject, EngineConstants.GO_HOSTILE_ON_PERCEIVE_PC, 0); //Go hostile engine.UT_CombatStart(gameObject, oAppear); } } if (bStealthed != EngineConstants.FALSE) { // ------------------------------------------------------------- // Stealth Check // ------------------------------------------------------------- if (engine.IsFollower(oAppear) != EngineConstants.FALSE && engine.Stealth_CheckSuccess(oAppear, gameObject) == EngineConstants.FALSE) { //WR_TriggerPerception(gameObject,oAppear); engine.DropStealth(oAppear); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PERCEPTION, "rules_core", "Stealth Check failed!"); #endif } else { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PERCEPTION, "rules_core", "Stealth Check Success!"); #endif } return; } if (nHostilityChanged != EngineConstants.FALSE) { //re-check hostility between self and creature. //The nHostile flag will not be correct in this case since the engine set the flag before the //xEvent was set. By the time we get the xEvent creature hostility towards each other will be different if (engine.IsObjectHostile(gameObject, oAppear) != EngineConstants.FALSE) nHostile = EngineConstants.TRUE; else nHostile = EngineConstants.FALSE; } // If the hostility changed, and the GameObject is not hostile, it means the GameObject was hostile and turned // non-hostile. This means that we need to run some combat-stopping logic that is usually run on a // perception disappear event, so we could remove this creature from combat state if needed. if (nHostilityChanged != EngineConstants.FALSE && nHostile == EngineConstants.FALSE) { engine.Combat_HandleCreatureDisappear(gameObject, oAppear); } // engine.Handle shouts // Triggering when perceiving a follower // NOTE: this needs to be triggered when triggering a follower since if the check was for "controlled" // the player might switch control and confuse the system if (engine.IsFollower(oAppear) != EngineConstants.FALSE && engine.UT_GetShoutsFlag(gameObject) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Perceived party member: Activating shouts"); #endif engine.SendEventOnDelayedShout(gameObject); // This will start the delayed xEvent loop } if (nHostile != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Perceived hostile: " + engine.GetTag(oAppear) + ", my combat state= " + engine.IntToString(engine.GetCombatState(gameObject))); #endif if (engine.IsFollower(gameObject) == EngineConstants.FALSE) { engine.AI_Threat_UpdateEnemyAppeared(gameObject, oAppear); } if (engine.GetCombatState(gameObject) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR", "COMBAT ACTIVE!"); #endif if (engine.IsFollower(gameObject) == EngineConstants.FALSE) { engine.SetCombatState(gameObject, EngineConstants.TRUE); engine.WR_ClearAllCommands(gameObject, EngineConstants.TRUE); if (engine.IsFollower(oAppear) != EngineConstants.FALSE) { engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_ENEMY_SIGHTED, oAppear); } } // --------------------------------------------------------- // If we are not the controlled creature, engage combat AI. // --------------------------------------------------------- if (engine.IsControlled(gameObject) == EngineConstants.FALSE) { if (engine.IsFollower(gameObject) == EngineConstants.FALSE && engine.GetLocalInt(gameObject, EngineConstants.AI_CUSTOM_AI_ACTIVE) != EngineConstants.FALSE) // custom AI active { engine.Ambient_Stop(gameObject); #if DEBUG engine.Log_Trace_AI("rules_core", "Executing CUSTOM AI"); #endif engine.SendEventHandleCustomAI(gameObject, null, -1, -1, -1); // } else if (engine.IsFollower(gameObject) == EngineConstants.FALSE) { // Initial call - all others should be when commands are completed engine.Ambient_Stop(gameObject); float fDistance = engine.GetDistanceBetween(gameObject, oAppear); if (fDistance > 25.0f && nHostilityChanged == EngineConstants.FALSE && engine.IsUsingMeleeWeapon(gameObject) == EngineConstants.FALSE) { nRand = engine.Engine_Random(EngineConstants.AI_TRIGGER_DELAY_RANDOM_RANGE) + 1; // randomizing 10 int values to determine a delay between 0.0f and EngineConstants.AI_TRIGGER_DELAY_RANDOM_RANGE fCombatDelay = engine.IntToFloat(nRand) / engine.IntToFloat(EngineConstants.AI_TRIGGER_DELAY_RANDOM_RANGE) * EngineConstants.AI_TRIGGER_DELAY_RANDOM_MAX; #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Triggering combat with a delay of: " + engine.FloatToString(fCombatDelay)); #endif xCommand cWait = engine.CommandWait(fCombatDelay); engine.WR_AddCommand(gameObject, cWait); } else { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Enemy perceived too close - not delaying start of combat"); #endif engine.AI_DetermineCombatRound(); } engine.SetFacingObject(gameObject, oAppear); } else if (engine.IsFollower(gameObject) != EngineConstants.FALSE) // non-followers get wait combat instead, above engine.AI_DetermineCombatRound(); } if (engine.GetLocalInt(gameObject, EngineConstants.AI_LIGHT_ACTIVE) == 1) { #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR", "LIGHT AI CREATURE: aborting rest of perception event"); #endif break; } // --------------------------------------------------------- // Force all allies into combat // --------------------------------------------------------- List<GameObject> arAllies = engine._AI_GetAllies(EngineConstants.COMMAND_TYPE_INVALID, -1); nSize = engine.GetArraySize(arAllies); xCommand cMove; int bIsStealthy = engine.IsStealthy(gameObject); #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR", "BOOM stealthy= " + engine.IntToString(bIsStealthy)); #endif for (i = 0; i < nSize; i++) { oAlly = arAllies[i]; if (engine.GetCombatState(oAlly) == EngineConstants.FALSE) { // Yaron, Feb 25 2008 - changing to move toward ally instead of perceiving enemy // Followers still trigger perception if (engine.IsFollower(oAlly) != EngineConstants.FALSE && engine.IsStealthy(gameObject) == EngineConstants.FALSE) { if (engine.WR_TriggerPerception(oAlly, oAppear) == EngineConstants.FALSE && engine.IsControlled(oAlly) == EngineConstants.FALSE && engine.GetMainControlled() == gameObject) { // TriggerPerception failed for an ally while I'm the main controlled // - Move to party leader Vector3 lLoc = engine.GetFollowerWouldBeLocation(oAlly); cMove = engine.CommandMoveToLocation(lLoc, EngineConstants.TRUE); engine.WR_AddCommand(oAlly, cMove); } else if (engine.IsControlled(oAlly) == EngineConstants.FALSE) // combat time // NOTE: this used to be delayed, but was removed becasue it casues followers // to linger behind the player sometimes when charging into combat { engine.AI_DetermineCombatRound(); } } else if (engine.IsFollower(oAlly) == EngineConstants.FALSE) // non party members { if (engine.GetLocalInt(oAlly, EngineConstants.AI_FLAG_STATIONARY) == 0 && engine.GetLocalInt(oAlly, EngineConstants.CLIMAX_ARMY_ID) == 0) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_AI, engine.GetCurrentScriptName(), "Bringing over ally: " + engine.GetTag(oAlly)); #endif //int nRand = Engine_Random(10) + 1; //float fDistanceToMove = IntToFloat(nRand); if (engine.GetLocalInt(gameObject, EngineConstants.AI_HELP_TEAM_STATUS) <= 1) // allow for 0 (not active) or 1 (active for special system) { engine.SetLocalInt(gameObject, EngineConstants.AI_HELP_TEAM_STATUS, EngineConstants.AI_HELP_TEAM_STATUS_NORMAL_ALLY_HELP_ACTIVE); cMove = engine.CommandMoveToObject(oAppear, EngineConstants.TRUE); engine.SetCreatureIsStatue(oAlly, EngineConstants.FALSE); engine.WR_ClearAllCommands(oAlly, EngineConstants.TRUE); engine.Ambient_Stop(oAlly); engine.WR_AddCommand(oAlly, cMove, EngineConstants.TRUE, EngineConstants.FALSE); } } } } } } else // IN combat, perceiving hostile // (can be when a stealth player goes out of stealth and drags enemies back to his party) { xCommand cCurrent = engine.GetCurrentCommand(gameObject); int nQSize = engine.GetCommandQueueSize(gameObject); if (engine.IsFollower(gameObject) != EngineConstants.FALSE && engine.IsControlled(gameObject) == EngineConstants.FALSE) { // a non-controlled follower peceiving hostile while doing nothing if (nQSize == 0 && engine.GetCommandType(cCurrent) == EngineConstants.COMMAND_TYPE_INVALID) { #if DEBUG engine.Log_Trace_AI("rules_core.EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR", "Non-controlled follower perceivng hostile while in combat state and not running any action"); #endif engine.AI_DetermineCombatRound(); } } } // ----------------------------------------------------------------- // engine.Set the game into combat camera if we perceive a hostile creature // and are not in combat mode // ----------------------------------------------------------------- if (engine.IsPartyMember(gameObject) != EngineConstants.FALSE) { int nMode = engine.GetGameMode(); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Party game mode: " + engine.IntToString(nMode)); #endif if (nMode == EngineConstants.GM_EXPLORE || nMode == EngineConstants.GM_DEAD) { if (engine.IsObjectHostile(gameObject, oAppear) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "PARTY perceived hostiles and not in combat yet - ENTERING COMBAT MODE"); #endif // ------------------------------------------------- // Play Enemy Sighted if controlled character... // ------------------------------------------------- if (engine.IsControlled(gameObject) != EngineConstants.FALSE) { engine.SSPlaySituationalSound(gameObject, EngineConstants.SOUND_SITUATION_ENEMY_SIGHTED, oAppear); } engine.WR_SetGameMode(EngineConstants.GM_COMBAT); } } // This handles ressurection while the party is already in combat mode and the rejoining // follower combat state does not match the party's else if (nMode == EngineConstants.GM_COMBAT && engine.GetCombatState(gameObject) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "RESSURECTED PARTY MEMBER: setting combat state ACTIVE"); #endif engine.SetCombatState(gameObject, EngineConstants.TRUE); } } } #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "tactic table: " + engine.IntToString(engine.GetPackageAI(gameObject))); #endif // handle creatures that should run away from hostiles (for example: city elf servant escorting the player) if (engine.GetPackageAI(gameObject) == 10130) // coward package engine.AI_HandleCowardFollower(oAppear); break; } // -------------------------------------------------------------------- // EngineConstants.EVENT_TYPE_ALLY_ATTACKED - AI EVENT // -------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_ALLY_ATTACKED: { GameObject oAlly = engine.GetEventCreatorRef(ref ev); GameObject oAttacker = engine.GetEventObjectRef(ref ev, 0); if (engine.IsDead(oAttacker) != EngineConstants.FALSE || engine.IsDying(oAttacker) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, engine.GetCurrentScriptName(), "Discarding EngineConstants.EVENT_TYPE_ALLY_ATTACKED (attacker dead or dying)", oAttacker); #endif return; } // Do not help ally if creature is stationary if (engine.GetLocalInt(gameObject, EngineConstants.AI_FLAG_STATIONARY) != EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_AI, engine.GetCurrentScriptName(), "Discarding EngineConstants.EVENT_TYPE_ALLY_ATTACKED (I'm stationary - can't move to help)"); #endif return; } // Just call perception and allow it to decide what to do with the attacker engine.WR_TriggerPerception(gameObject, oAttacker); engine.WR_TriggerPerception(oAttacker, gameObject); break; } /*case EngineConstants.EVENT_TYPE_DEATH: { engine.Log_Trace(EngineConstants.LOG_CHANNEL_CHARACTER,"rules_core.EngineConstants.EVENT_TYPE_AFTER_DEATH", "Forcing AI level to very low!"); engine.SetAILevel(gameObject,CSERVERAIMASTER_AI_LEVEL_VERY_LOW); engine.WR_SetCombatState(gameObject,EngineConstants.FALSE); break; } */ case EngineConstants.EVENT_TYPE_RESURRECTION: { // -------------------------------------------------------------------- // //Track engine.Item Equip Events for party // -------------------------------------------------------------------- #if SKYNET //TrackCreatureEvent(nEventType,gameObject); #endif // -------------------------------------------------------------------- // Restart AI level after it was frozen... // -------------------------------------------------------------------- #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_CHARACTER, "rules_core.EngineConstants.EVENT_TYPE_RESURRECTION", "Forcing AI level normal, then unlocking it!"); #endif engine.SetAILevel(gameObject, EngineConstants.CSERVERAIMASTER_AI_LEVEL_HIGH); engine.SetAILevel(gameObject, EngineConstants.CSERVERAIMASTER_AI_LEVEL_INVALID); break; } case EngineConstants.EVENT_TYPE_CONVERSATION: { // Player clicked on this GameObject or dialog initiated using a script // Need to initiate the dialog itself. GameObject oInitiator = engine.GetEventCreatorRef(ref ev); string rConversation = engine.GetEventResourceRef(ref ev, 0); // default is "" string sConv = engine.ResourceToString(rConversation); engine.UT_Talk(gameObject, oInitiator, rConversation); break; } case EngineConstants.EVENT_TYPE_OUT_OF_AMMO: { engine.UI_DisplayMessage(gameObject, EngineConstants.UI_MESSAGE_OUT_OF_AMMO); // Doing nothing now since the AI checks for ammo when it tries to use ranged weapons, // but we may want to add here a static flag setup so the AI can read the flag instead break; } // --------------------------------------------------------------------- // Debug Event, do not use in production scripts // Kickstart the AI if it was frozen out // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_DEBUG_KICKSTART_AI: { engine.AI_DetermineCombatRound(); break; } // --------------------------------------------------------------------- // Creature ran out of mana or stamina // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_MANA_STAM_DEPLETED: { // ----------------------------------------------------------------- // Ability system has some events happening when running out of // a string (e.g. deactivating berserk). // ----------------------------------------------------------------- engine.Ability_HandleEventOutOfManaStamina(gameObject); break; } case EngineConstants.EVENT_TYPE_CONFUSION_CALLBACK: { engine.Effects_HandleConfusionCallback(gameObject); break; } case EngineConstants.EVENT_TYPE_SUMMON_DIED: { engine.EffectSummon_HandleEventSummonDied(gameObject, engine.GetEventIntegerRef(ref ev, 0)); break; } // --------------------------------------------------------------------- // Georg: Because DropStealth itself generates 3-4 levels of recursion // on the stack, some scripts are using a delayed xEvent to terminate // stealth. // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_DROP_STEALTH: { if (engine.IsStealthy(gameObject) != EngineConstants.FALSE) { engine.DropStealth(gameObject); } break; } // ----------------------------------------------------------------- // EngineConstants.EVENT_TYPE_SET_OBJECT_ACTIVE - Changes creature's active state // ----------------------------------------------------------------- case EngineConstants.EVENT_TYPE_SET_OBJECT_ACTIVE: { int nActive = engine.GetEventIntegerRef(ref ev, 0); #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS, "rules_core", "creature set to active=" + engine.IntToString(nActive)); #endif int nAnimation = engine.GetEventIntegerRef(ref ev, 2); int bCallAI = engine.GetEventIntegerRef(ref ev, 3); if (bCallAI != EngineConstants.FALSE) { engine.AI_ExecuteAppearStomp(ev); break; } //Vector3 lLoc = engine.GetEventVectorRef(ref ev, 0); if (nAnimation == 0) nAnimation = -1; engine.WR_SetObjectActive(gameObject, nActive, nAnimation); // Activating summoned creature if (engine.GetEventIntegerRef(ref ev, 1) != 0) { // for summoned creatures it should come here only to REMOVE them. Adding is done in ability_summon_h engine.WR_SetFollowerState(gameObject, engine.GetEventIntegerRef(ref ev, 1)); } break; } // ----------------------------------------------------------------- // EngineConstants.EVENT_TYPE_OBJECT_ACTIVE - Creature changed to active state // ----------------------------------------------------------------- case EngineConstants.EVENT_TYPE_OBJECT_ACTIVE: { engine.Ambient_SpawnStart(gameObject); break; } // ----------------------------------------------------------------- // EngineConstants.EVENT_TYPE_DESTROY_OBJECT - Object should be destroyed // ----------------------------------------------------------------- case EngineConstants.EVENT_TYPE_DESTROY_OBJECT: { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_CHARACTER, "rules_core", "GameObject should be destroyed"); #endif engine.Safe_Destroy_Object(gameObject, 0); break; } // --------------------------------------------------------------------- // // --------------------------------------------------------------------- case EngineConstants.EVENT_TYPE_GIFT_ITEM: { GameObject oItem = engine.GetEventObjectRef(ref ev, 0); int nFollower = engine.Approval_GetFollowerIndex(gameObject); int nApprovalChange = engine.Approval_HandleGift(nFollower, oItem); if (engine.IsObjectValid(oItem) == EngineConstants.FALSE) { #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS, "rules_core:EngineConstants.EVENT_TYPE_GIFT_ITEM", "INVALID EngineConstants.ITEM!"); #endif engine.Warning("ERROR! Invalid item was gifted"); break; } #if DEBUG engine.Log_Trace(EngineConstants.LOG_CHANNEL_SYSTEMS, "rules_core:EngineConstants.EVENT_TYPE_GIFT_ITEM", "item: " + engine.GetTag(oItem) + ", pending approval change: " + engine.IntToString(nApprovalChange)); #endif engine.SendHandleModuleGift(gameObject, oItem, nApprovalChange); break; } } }
/*----------------------------------------------------------------------------- * @brief Handles EngineConstants.EVENT_TYPE_PLACEABLE_ONCLICK placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleClicked(xEvent ev) { }
public override int StartingConditional(xEvent eParms) { //xEvent eParms = engine.GetCurrentEvent(); // Contains all input parameters int nType = engine.GetEventTypeRef(ref eParms); // GET or SET call string strPlot = engine.GetEventStringRef(ref eParms, 0); // Plot GUID int nFlag = engine.GetEventIntegerRef(ref eParms, 1); // The bit flag # being affected GameObject oParty = engine.GetEventCreatorRef(ref eParms); // The owner of the plot table for this script GameObject oConversationOwner = engine.GetEventObjectRef(ref eParms, 0); // Owner on the conversation, if any int nResult = EngineConstants.FALSE; // used to return value for DEFINED GET xEvents GameObject oPC = engine.GetHero(); engine.plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info if (nType == EngineConstants.EVENT_TYPE_SET_PLOT) // actions -> normal flags only { int nValue = engine.GetEventIntegerRef(ref eParms, 2); // On SET call, the value about to be written (on a normal SET that should be '1', and on a 'clear' it should be '0') int nOldValue = engine.GetEventIntegerRef(ref eParms, 3); // On SET call, the current flag value (can be either 1 or 0 regardless if it's a set or clear xEvent) // IMPORTANT: The flag value on a SET xEvent is set only AFTER this script finishes running! switch (nFlag) { case EngineConstants.DEMO_QUEST_ACCEPTED: { //Gives the inkeeper's key to the player. The key itself //is a "plot item", so we don't need to do anything fancy //to prevent the player from dropping it - it'll go into the //plot item section of his inventory until such time as we //remove it using another script. engine.UT_AddItemToInventory(EngineConstants.DEMO_INKEEPER_KEY_R); break; } case EngineConstants.DEMO_BACK_ROOM_OPENED: { //We don't want to blow up the barrel every time the lever's pulled, //just the first time. So test if this flag's been set already. if (engine.WR_GetPlotFlag(EngineConstants.PLT_DEMO000PL_MAIN, EngineConstants.DEMO_BACK_ROOM_OPENED) == EngineConstants.FALSE) { //Blow up the barrel and unlock the door GameObject oDoor = engine.UT_GetNearestObjectByTag(oPC, EngineConstants.DEMO_KITCHEN_DOOR, EngineConstants.FALSE); GameObject oBarrel = engine.UT_GetNearestObjectByTag(oPC, EngineConstants.DEMO_BARRIER_BARREL, EngineConstants.FALSE); GameObject oExplosion = engine.UT_GetNearestObjectByTag(oPC, EngineConstants.DEMO_EXPLOSION_TARGET, EngineConstants.FALSE); //triggers the blast VFX engine.ApplyEffectOnObject(EngineConstants.EFFECT_DURATION_TYPE_INSTANT, engine.EffectVisualEffect(EngineConstants.VFX_FIREBALL_IMPACT), oExplosion); //Makes the barrel "go away" engine.SetObjectActive(oBarrel, EngineConstants.FALSE); //Changes the door to its "destroyed" state, which makes it //passable. engine.DestroyPlaceable(oDoor); } break; } case EngineConstants.DEMO_BANDIT_HOSTILE: { //This causes all members of the bandit's "team" (the bandit and //the other bar patrons) to turn hostile. Since they're in the presence //of the player already, they'll immediately percieve him and initiate //combat. engine.UT_TeamGoesHostile(EngineConstants.BANDIT_TEAM); //Turn hostile team red List<GameObject> arTeam = engine.UT_GetTeam(EngineConstants.BANDIT_TEAM); for (int nIndex = 0; nIndex < engine.GetArraySize(arTeam); nIndex++) { GameObject _member = arTeam[nIndex]; GameObject _sphere = _member.transform.Find("Sphere").gameObject; _sphere.GetComponent<Renderer>().material.color = Color.red; } //During debug manually add the player to the bandits threat target for (int nIndex = 0; nIndex < engine.GetArraySize(arTeam); nIndex++) { GameObject _member = arTeam[nIndex]; engine.SetEnemy(_member, engine.GetHero()); } //During debug manually add the player to the bandits threat target for (int nIndex = 0; nIndex < engine.GetArraySize(arTeam); nIndex++) { GameObject _member = arTeam[nIndex]; xEvent ev = engine.Event(EngineConstants.EVENT_TYPE_PERCEPTION_APPEAR); engine.SetEventObjectRef(ref ev, 0, engine.GetHero()); engine.SetEventIntegerRef(ref ev, 0, EngineConstants.TRUE);//Hostile True engine.SetEventIntegerRef(ref ev, 1, EngineConstants.FALSE);//Stealth false engine.SetEventIntegerRef(ref ev, 2, EngineConstants.TRUE);//Hostility changed True engine.SignalEvent(_member, ev); } engine.WR_SetGameMode(EngineConstants.GM_COMBAT); //end DHK break; } case EngineConstants.DEMO_BARKEEP_JOINED_PARTY: { //When the sword quest is done the barkeep will offer to join //the party. If the offer is accepted, this code handles adding //him. GameObject oBarkeep = engine.UT_GetNearestCreatureByTag(oPC, EngineConstants.DEMO_BARKEEP); //remove the plot-related properties, since they'd interfere //with him functioning as a normal party member engine.SetPlotGiver(oBarkeep, EngineConstants.FALSE); engine.SetPlot(oBarkeep, EngineConstants.FALSE); engine.UT_HireFollower(oBarkeep); break; } case EngineConstants.DEMO_SWORD_RETURNED: { //The player can't discard plot items on his own, so make sure to remove the //sword here. Create a separate non-plot sword for the innkeeper //to use and leave it in his inventory, the player will never know //that the innkeeper had it all along. engine.UT_RemoveItemFromInventory(EngineConstants.DEMO_INKEEPERS_SWORD_R); //Once the sword quest is done we want to open up a new area //on the map for the player. GameObject oMapPinRoad = engine.GetObjectByTag(EngineConstants.DEMO_ROAD_MAP_PIN); //engine.WR_SetWorldMapLocationStatus(oMapPinRoad, WM_LOCATION_ACTIVE); break; } } } else // EVENT_TYPE_GET_PLOT -> defined conditions only { switch (nFlag) { case EngineConstants.DEMO_DECLINED_QUEST: { //This is a "defined" plot flag. When the plot is checked //to see whether the flag is true or false, its status is //determined using the following code. if ( engine.WR_GetPlotFlag(EngineConstants.PLT_DEMO000PL_MAIN, EngineConstants.DEMO_TALKED_TO_BARKEEP) == EngineConstants.TRUE && engine.WR_GetPlotFlag(EngineConstants.PLT_DEMO000PL_MAIN, EngineConstants.DEMO_QUEST_ACCEPTED) == EngineConstants.FALSE ) { return EngineConstants.TRUE; } else { return EngineConstants.FALSE; } } } } engine.plot_OutputDefinedFlag(eParms, nResult); return nResult; }
/*----------------------------------------------------------------------------- * @brief Handles the EngineConstants.EVENT_TYPE_SPAWN placeable event. * * @param ev The xEvent being handled. *-----------------------------------------------------------------------------*/ public void Placeable_HandleSpawned(xEvent ev) { // Database spawn tracking. High volume xEvent so disabled by default. /*if (TRACKING_TRACK_SPAWN_EVENTS) { //TrackPlaceableEvent(GetEventTypeRef(ref ev), gameObject, null, GetAppearanceType(gameObject)); }*/ if (GetLocalInt(gameObject, EngineConstants.PLC_SPAWN_NON_INTERACTIVE) == 1) { Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PLACEABLES, GetCurrentScriptName() + "Spawning placeable non-interactive"); SetObjectInteractive(gameObject, EngineConstants.FALSE); } //Codex placeables will spawn non-interactive if the player already has the entry. string sCodexPlot = GetLocalString(gameObject, EngineConstants.PLC_CODEX_PLOT); int nCodexFlag = GetLocalInt(gameObject, EngineConstants.PLC_CODEX_FLAG); if ((nCodexFlag >= 0) && (sCodexPlot != "")) { if (WR_GetPlotFlag(sCodexPlot, nCodexFlag) != EngineConstants.FALSE) { SetObjectInteractive(gameObject, EngineConstants.FALSE); } } // Generate random treasure if (GetPlaceableBaseType(gameObject) == EngineConstants.PLACEABLE_TYPE_CHEST) { TreasureGenerate(gameObject); } // Automatically arm trap if no owner. if (GetObjectActive(gameObject) != EngineConstants.FALSE && Trap_GetType(gameObject) > 0 && IsObjectValid(Trap_GetOwner(gameObject)) == EngineConstants.FALSE) { Trap_ArmTrap(gameObject, null, 0.0f); } // Set initial health if (GetMaxHealth(gameObject) <= 1.1f) { int nHealth = GetM2DAInt(EngineConstants.TABLE_PLACEABLE_TYPES, "Health", GetAppearanceType(gameObject)); if (nHealth > 1) SetMaxHealth(gameObject, nHealth); } // Apply crust effect int nCrustEffect = GetM2DAInt(EngineConstants.TABLE_PLACEABLE_TYPES, "CrustVFX", GetAppearanceType(gameObject)); if (nCrustEffect != EngineConstants.FALSE) { Log_Trace(EngineConstants.LOG_CHANNEL_EVENTS_PLACEABLES, GetCurrentScriptName() + ".Placeable_HandleSpawned()", " Applying CrustVFX: " + ToString(nCrustEffect)); ApplyEffectVisualEffect(gameObject, gameObject, nCrustEffect, EngineConstants.EFFECT_DURATION_TYPE_PERMANENT, 0.0f); } }