public bool OnStartCombat(GameObject attachee, GameObject triggerer, bool generated_from_timed_event_call, int talk_stage) { if (attachee.IsUnconscious()) { return(RunDefault); } // if !generated_from_timed_event_call and attachee.distance_to( party_closest(attachee) ) > 45: // attachee.move( party_closest(attachee).location, 0 , 0) // for pp in range(0, 41): // attachee.scripts[pp] = 998 // game.leader.ai_follower_add(attachee) // #game.timevent_add( lareth_abandon, (attachee, triggerer), 20, 1) var curr = attachee.GetStat(Stat.hp_current) - attachee.GetStat(Stat.subdual_damage); var maxx = attachee.GetStat(Stat.hp_max); var xx = attachee.GetLocation() & (65535); var hp_percent_lareth = 100 * curr / maxx; var ggv400 = GetGlobalVar(400); var ggv401 = GetGlobalVar(401); var pad3 = attachee.GetInt(obj_f.npc_pad_i_3); if ((attachee.GetMap() == 5005) && (party_too_far_from_lareth(attachee)) && !generated_from_timed_event_call) { if (((pad3 & 0x4) == 0)) { // Delay for one round, letting him cast Shield of Faith - he'll need it :) pad3 |= 0x4; attachee.SetInt(obj_f.npc_pad_i_3, pad3); return(RunDefault); } // Party is too far from Lareth, gotta nudge him in the right direction // spawn a beacon and change Lareth's strat to approach it locXY beacon_loc; if (xx > 478) { beacon_loc = new locXY(498, 550); } else { beacon_loc = new locXY(487, 540); } var obj_beacon = GameSystems.MapObject.CreateObject(14074, beacon_loc); obj_beacon.SetObjectFlag(ObjectFlag.DONTDRAW); obj_beacon.SetObjectFlag(ObjectFlag.CLICK_THROUGH); obj_beacon.Move(beacon_loc, 0, 0); obj_beacon.SetBaseStat(Stat.dexterity, -30); obj_beacon.SetInt(obj_f.npc_pad_i_3, 0x100); obj_beacon.Attack(SelectedPartyLeader); obj_beacon.AddToInitiative(); attachee.SetInt(obj_f.pad_i_0, attachee.GetInt(obj_f.critter_strategy)); // Record original strategy attachee.SetInt(obj_f.critter_strategy, 80); // set Lareth's strat to "seek beacon" var grease_detected = false; foreach (var spell_obj in ObjList.ListCone(attachee, ObjectListFilter.OLC_GENERIC, 40, 0, 360)) { // Check for active GREASE spell object if (spell_obj.GetInt(obj_f.secretdoor_dc) == 200 + (1 << 15)) { grease_detected = true; } } if (grease_detected) { // In case Lareth slips and doesn't execute his san_end_combat (wherein the beacon object is destroyed) - spawn a couple of timed events to guarantee the beacon doesn't survive StartTimer(3700, () => kill_beacon_obj(obj_beacon, attachee), true); StartTimer(3900, () => kill_beacon_obj(obj_beacon, attachee), true); } return(RunDefault); } // strategy 81 - Approach Party strategy if (attachee.GetInt(obj_f.critter_strategy) == 81 && !generated_from_timed_event_call) { if (ScriptDaemon.can_see_party(attachee)) { attachee.SetInt(obj_f.critter_strategy, 82); } } if (attachee.GetInt(obj_f.critter_strategy) != 81 && !generated_from_timed_event_call) { // Should Lareth cast Obscuring Mist? // First, find closest party member - the most likely target for an archer var closest_pc_1 = SelectedPartyLeader; foreach (var pc in PartyLeader.GetPartyMembers()) { if (pc.DistanceTo(attachee) < closest_pc_1.DistanceTo(attachee)) { closest_pc_1 = pc; } } // Then, check for spell objects with the Obscuring Mist ID, which are also identified as active var player_in_obscuring_mist = 0; foreach (var spell_obj in ObjList.ListCone(closest_pc_1, ObjectListFilter.OLC_GENERIC, 30, 0, 360)) { if (spell_obj.GetInt(obj_f.secretdoor_dc) == 333 + (1 << 15) && spell_obj.DistanceTo(closest_pc_1) <= 17.5f) { player_in_obscuring_mist = 1; } } var player_cast_web = false; var player_cast_entangle = false; foreach (var spell_obj in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_GENERIC)) { if (spell_obj.GetInt(obj_f.secretdoor_dc) == 531 + (1 << 15)) { player_cast_web = true; } if (spell_obj.GetInt(obj_f.secretdoor_dc) == 153 + (1 << 15)) { player_cast_entangle = true; } } // Assess level of ranged weapon threat var ranged_threat = 0; foreach (var pc in PartyLeader.GetPartyMembers()) { var pc_weap = pc.ItemWornAt(EquipSlot.WeaponPrimary).GetInt(obj_f.weapon_type); if ((new[] { 14, 17, 46, 48, 68 }).Contains(pc_weap) && !pc.IsUnconscious()) { // 14 - light crossbow // 17 - heavy crossbow // 46 - shortbow // 48 - longbow // 68 - repeating crossbow if (ranged_threat == 0) { ranged_threat = 1; } if (pc.HasFeat(FeatId.POINT_BLANK_SHOT) || (pc.GetStat(Stat.level_fighter) + pc.GetStat(Stat.level_ranger)) >= 1) { if (ranged_threat < 2) { ranged_threat = 2; } } if (pc.HasFeat(FeatId.PRECISE_SHOT) && (pc.GetStat(Stat.level_fighter) + pc.GetStat(Stat.level_ranger)) >= 1) { if (ranged_threat < 3) { ranged_threat = 3; } } } } if ((attachee.GetMap() == 5005 && xx > 478) && (((ggv401 >> 25) & 3) == 0) && ((ranged_threat == 3) || (ranged_threat > 1 && player_in_obscuring_mist == 1) || (ranged_threat > 0 && (player_cast_entangle || player_cast_web)))) { // Cast Obscuring Mist, if: // 1. Haven't cast it yet - (ggv401 >> 25) & 3 // 2. Ranged threat exists (emphasized when player casts web or is in obscuring mist) // Give him a potion of Obscuring Mist, to simulate him having that scroll (just like I do...) if (attachee.FindItemByProto(8899) == null) { attachee.GetItem(GameSystems.MapObject.CreateObject(8899, attachee.GetLocation())); } ggv401 += 1 << 25; SetGlobalVar(401, ggv401); var lareth_is_threatened = 0; if (closest_pc_1.DistanceTo(attachee) <= 3) { lareth_is_threatened = 1; } if (lareth_is_threatened == 1) { attachee.SetInt(obj_f.critter_strategy, 85); // Obscuring Mist + 5ft step } else { attachee.SetInt(obj_f.critter_strategy, 86); // Just Obscuring Mist } } else if (((pad3 & (2)) == 0) && (player_cast_entangle || player_cast_web)) { attachee.SetInt(obj_f.critter_strategy, 87); // Dispel strat pad3 |= (2); attachee.SetInt(obj_f.npc_pad_i_3, pad3); } else if (attachee.GetMap() == 5005 && player_entrenched_in_corridor(attachee)) { attachee.SetInt(obj_f.critter_strategy, 89); } else { attachee.SetInt(obj_f.critter_strategy, 82); } } if ((hp_percent_lareth < 50) && (!generated_from_timed_event_call || generated_from_timed_event_call && talk_stage == 667)) { if ((ggv400 & (0x40)) == 0) { GameObject found_pc = null; var obj_list = new List <GameObject>(); using var firstList = ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_NPC); obj_list.AddRange(firstList); // Extending the range a little... foreach (var obj in ObjList.ListVicinity(attachee.GetLocation().OffsetTiles(-35, 0), ObjectListFilter.OLC_NPC)) { if (!((obj_list).Contains(obj))) { obj_list.Add(obj); } } foreach (var obj in ObjList.ListVicinity(attachee.GetLocation().OffsetTiles(35, 0), ObjectListFilter.OLC_NPC)) { if (!((obj_list).Contains(obj))) { obj_list.Add(obj); } } foreach (var obj in obj_list) { foreach (var pc in SelectedPartyLeader.GetPartyMembers()) { if (pc.type == ObjectType.pc && !pc.IsUnconscious()) { found_pc = pc; } obj.AIRemoveFromShitlist(pc); obj.SetReaction(pc, 50); obj.RemoveFromInitiative(); if (pc.type == ObjectType.npc) { pc.AIRemoveFromShitlist(obj); } } foreach (var obj2 in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_ALL)) { if (obj2.type == ObjectType.pc || obj2.type == ObjectType.npc) { obj2.SetReaction(obj, 50); try { obj2.AIRemoveFromShitlist(obj); } finally { var dummy = 1; } obj2.RemoveFromInitiative(); } } } if (!generated_from_timed_event_call) { StartTimer(100, () => OnStartCombat(attachee, triggerer, true, 667), true); } else if (found_pc != null) { ggv400 |= 0x40; SetGlobalVar(400, ggv400); SetGlobalFlag(834, true); found_pc.BeginDialog(attachee, 160); return(SkipDefault); } } } else if (!generated_from_timed_event_call && !GetGlobalFlag(834)) { if (((ggv401 >> 15) & 7) == 0) { ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (((ggv401 >> 15) & 7) == 1) { var closest_distance_1 = SelectedPartyLeader.DistanceTo(attachee); foreach (var pc in GameSystems.Party.PartyMembers) { closest_distance_1 = Math.Min(closest_distance_1, pc.DistanceTo(attachee)); } if (closest_distance_1 < 45) { for (var ppq = 3; ppq < 26; ppq++) { StartTimer(ppq * 2500 + RandomRange(0, 20), () => OnStartCombat(attachee, triggerer, true, ppq), true); } ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } } } else if (generated_from_timed_event_call && !GetGlobalFlag(834)) { if ((hp_percent_lareth > 75) && (ggv400 & 0x10) == 0 && !attachee.D20Query(D20DispatcherKey.QUE_Prone)) { if (talk_stage >= 3 && ((ggv401 >> 15) & 31) == 2) { attachee.FloatLine(6000, triggerer); Sound(4201, 1); Sound(4201, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 3 && ((ggv401 >> 15) & 31) == 3) { Sound(4202, 1); Sound(4202, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 3 && ((ggv401 >> 15) & 31) == 4) { Sound(4203, 1); Sound(4203, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 8 && ((ggv401 >> 15) & 31) == 5) { attachee.FloatLine(6001, triggerer); Sound(4204, 1); Sound(4204, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 8 && ((ggv401 >> 15) & 31) == 6) { Sound(4205, 1); Sound(4205, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 13 && ((ggv401 >> 15) & 31) == 7) { attachee.FloatLine(6002, triggerer); Sound(4206, 1); Sound(4206, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 13 && ((ggv401 >> 15) & 31) == 8) { Sound(4207, 1); Sound(4207, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 18 && ((ggv401 >> 15) & 31) == 9) { attachee.FloatLine(6003, triggerer); Sound(4208, 1); Sound(4208, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 18 && ((ggv401 >> 15) & 31) == 10) { Sound(4209, 1); Sound(4209, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 22 && ((ggv401 >> 15) & 31) == 11) { attachee.FloatLine(6004, triggerer); Sound(4210, 1); Sound(4210, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 22 && ((ggv401 >> 15) & 31) == 12) { attachee.FloatLine(6004, triggerer); Sound(4211, 1); Sound(4211, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } else if (talk_stage >= 22 && ((ggv401 >> 15) & 31) == 13) { attachee.FloatLine(6004, triggerer); Sound(4212, 1); Sound(4212, 1); ggv401 += 1 << 15; SetGlobalVar(401, ggv401); } } else if ((hp_percent_lareth <= 75) && (ggv400 & 0x10) == 0) { if (((ggv401 >> 15) & 31) > 2) { attachee.FloatLine(6005, triggerer); Sound(4200, 1); Sound(4200, 1); } StartTimer(5500, () => OnStartCombat(attachee, triggerer, true, 667), true); ggv400 |= 0x10; SetGlobalVar(400, ggv400); } } // Spiritual Weapon Shenanigens # CombatStandardRoutines.Spiritual_Weapon_Begone(attachee); return(RunDefault); }
public static bool san_enter_combat_backup_with_beacon_shit(GameObject attachee, GameObject triggerer) { Livonya.tag_strategy(attachee); if (attachee.GetNameId() == 14811) // The Beacon { attachee.SetScriptId(ObjScriptEvent.EndCombat, 446); // end combat round script attachee.FloatMesFileLine("mes/script_activated.mes", 13, TextFloaterColor.Red); return(RunDefault); } if ((!ScriptDaemon.can_see_party(attachee) && ScriptDaemon.is_far_from_party(attachee, 10)) || ScriptDaemon.is_far_from_party(attachee, 40)) { if (ScriptDaemon.is_far_from_party(attachee, 70)) { var joe = Utilities.party_closest(attachee); ScriptDaemon.encroach(attachee, joe); } attachee.SetInt(obj_f.critter_strategy, 119); // Seek out low ac beacon AttachParticles("sp-Hold Person", attachee); if (ScriptDaemon.get_v("Beacon_Active") == 0) { var top_path = 0; var bottom_path = 0; foreach (var pc in GameSystems.Party.PartyMembers) { if (ScriptDaemon.within_rect_by_corners(pc, 467, 360, 467, 388) && !pc.IsUnconscious()) { top_path = top_path + 1; } if (ScriptDaemon.within_rect_by_corners(pc, 504, 355, 504, 385) && !pc.IsUnconscious()) { bottom_path = bottom_path + 1; } } int primary_beacon_x; int primary_beacon_y; int tertiary_beacon_x; int tertiary_beacon_y; if (top_path > bottom_path) { primary_beacon_x = 470; primary_beacon_y = 388; tertiary_beacon_x = 492; tertiary_beacon_y = 387; } else { primary_beacon_x = 492; primary_beacon_y = 387; tertiary_beacon_x = 470; tertiary_beacon_y = 388; } var beacon_loc = new locXY(primary_beacon_x, primary_beacon_y); var beacon3_loc = new locXY(tertiary_beacon_x, tertiary_beacon_y); var beacon = GameSystems.MapObject.CreateObject(14811, beacon_loc); beacon.Move(new locXY(470, 388), 0, 0); beacon.SetInt(obj_f.npc_ac_bonus, -50); beacon.SetBaseStat(Stat.dexterity, -70); // causes problems at end of round, or does it? // beacon.object_flag_set(OF_DONTDRAW) # this causes combat to lag at the beacon's turn beacon.SetObjectFlag(ObjectFlag.CLICK_THROUGH); beacon.AddToInitiative(); beacon.SetInitiative(-20); UiSystems.Combat.Initiative.UpdateIfNeeded(); beacon.SetScriptId(ObjScriptEvent.EndCombat, 446); // end combat round // beacon.scripts[14] = 446 # exit combat AttachParticles("sp-hold person", beacon); var beacon2 = GameSystems.MapObject.CreateObject(14811, new locXY(483, 395)); beacon2.Move(new locXY(483, 395), 0, 0); beacon2.SetInt(obj_f.npc_ac_bonus, -40); // beacon2.object_flag_set(OF_DONTDRAW) beacon2.SetObjectFlag(ObjectFlag.CLICK_THROUGH); beacon2.AddToInitiative(); beacon2.SetInitiative(-21); UiSystems.Combat.Initiative.UpdateIfNeeded(); AttachParticles("sp-hold person", beacon2); var beacon3 = GameSystems.MapObject.CreateObject(14811, beacon3_loc); beacon3.Move(beacon3_loc, 0, 0); beacon3.SetInt(obj_f.npc_ac_bonus, -30); // beacon3.object_flag_set(OF_DONTDRAW) beacon3.SetObjectFlag(ObjectFlag.CLICK_THROUGH); beacon3.AddToInitiative(); beacon3.SetInitiative(-23); UiSystems.Combat.Initiative.UpdateIfNeeded(); AttachParticles("sp-hold person", beacon3); ScriptDaemon.set_v("Beacon_Active", 3); } } else if (ScriptDaemon.is_far_from_party(attachee, 75)) { var joe = Utilities.party_closest(attachee); ScriptDaemon.encroach(attachee, joe); } else { Livonya.get_melee_strategy(attachee); } // Tried changing their standpoint midfight, didn't work. // attachee.standpoint_set(STANDPOINT_DAY, attachee.obj_get_int(obj_f_npc_pad_i_3) - 342 + 500) // attachee.standpoint_set(STANDPOINT_NIGHT, attachee.obj_get_int(obj_f_npc_pad_i_3) - 342 + 500) // if attachee.obj_get_int(obj_f_npc_pad_i_3) == 361 or attachee.obj_get_int(obj_f_npc_pad_i_3) == 362: #sentry standpoints // hl(attachee) // xx = 482 // yy = 417 // for npc in game.obj_list_vicinity(location_from_axis(xx,yy), OLC_NPC ): // if npc.leader_get() == OBJ_HANDLE_NULL: // npc.standpoint_set(STANDPOINT_DAY, npc.obj_get_int(obj_f_npc_pad_i_3) - 342 + 500) // npc.standpoint_set(STANDPOINT_NIGHT, npc.obj_get_int(obj_f_npc_pad_i_3) - 342 + 500) // npc.npc_flag_set(ONF_KOS) // npc.npc_flag_unset(ONF_KOS_OVERRIDE) return(RunDefault); }