コード例 #1
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        while ((attachee.FindItemByName(8903) != null))
        {
            attachee.FindItemByName(8903).Destroy();
        }

        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        if (attachee.GetLeader() != null) // Don't wanna f**k up charmed enemies
        {
            return(RunDefault);
        }

        var closest_jones = Utilities.party_closest(attachee, exclude_warded: true);

        if (attachee.DistanceTo(closest_jones) > 30 && !attachee.HasCondition(SpellEffects.SpellDimensionalAnchor))
        {
            attachee.PendingSpellsToMemorized();
            attachee.SetInt(obj_f.critter_strategy, 110);
        }
        else if (closest_jones == Utilities.party_closest(attachee, true, 2))
        {
            attachee.SetInt(obj_f.critter_strategy, 453);
        }
        else
        {
            CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        }

        return(RunDefault);
    }
コード例 #2
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        while ((attachee.FindItemByName(8903) != null))
        {
            attachee.FindItemByName(8903).Destroy();
        }

        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        if ((Utilities.obj_percent_hp(attachee) < 75))
        {
            GameObject found_pc = null;
            foreach (var pc in GameSystems.Party.PartyMembers)
            {
                if (pc.type == ObjectType.pc)
                {
                    found_pc = pc;
                    attachee.AIRemoveFromShitlist(pc);
                }
            }

            if (found_pc != null)
            {
                Co8.StopCombat(attachee, 1);
                found_pc.BeginDialog(attachee, 1);
                DetachScript();
                return(SkipDefault);
            }
        }

        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #3
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        if (attachee.GetMap() == 5002) // moathouse courtyard
        {
            foreach (var npc in ObjList.ListVicinity(new locXY(477, 463), ObjectListFilter.OLC_NPC))
            {
                if (npc.GetNameId() == 14070 && npc.GetLeader() == null && !npc.IsUnconscious())
                {
                    npc.Attack(SelectedPartyLeader);
                }
            }
        }

        if (((!GetGlobalFlag(833) && attachee.GetMap() == 5065 && !GetGlobalFlag(835) && !GetGlobalFlag(849)) || (GetGlobalFlag(839) && attachee.GetMap() == 5065 && !GetGlobalFlag(840) && !GetGlobalFlag(849))))
        {
            return(SkipDefault);
        }

        // THIS IS USED FOR BREAK FREE
        // found_nearby = 0
        // for obj in game.party[0].group_list():
        // if (obj.distance_to(attachee) <= 3 and obj.stat_level_get(stat_hp_current) >= -9):
        // found_nearby = 1
        // if found_nearby == 0:
        // while(attachee.item_find(8903) != OBJ_HANDLE_NULL):
        // attachee.item_find(8903).destroy()
        // #if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // #	create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #4
0
 public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
 {
     // THIS IS USED FOR BREAK FREE
     // found_nearby = 0
     // for obj in game.party[0].group_list():
     // if (obj.distance_to(attachee) <= 9 and obj.stat_level_get(stat_hp_current) >= -9):
     // found_nearby = 1
     // if found_nearby == 0:
     // while(attachee.item_find(8903) != OBJ_HANDLE_NULL):
     // attachee.item_find(8903).destroy()
     // #if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
     // #	create_item_in_inventory( 8903, attachee )
     // attachee.d20_send_signal(S_BreakFree)
     // Spiritual Weapon Shenanigens	#
     CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
     return(RunDefault);
 }
コード例 #5
0
    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);
    }
コード例 #6
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        while ((attachee.FindItemByName(8903) != null))
        {
            attachee.FindItemByName(8903).Destroy();
        }

        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        if ((attachee.GetNameId() == 14328 && RandomRange(1, 100) <= 40)) // Bodak Death Gaze
        {
            attachee.PendingSpellsToMemorized();
        }

        if ((attachee.GetNameId() == 14309 && RandomRange(1, 100) <= 25)) // Gorgon Breath Attack
        {
            attachee.PendingSpellsToMemorized();
        }

        if ((attachee.GetNameId() == 14109 && RandomRange(1, 100) <= 25)) // Ice Lizard Breath Attack
        {
            attachee.PendingSpellsToMemorized();
        }

        if ((attachee.GetNameId() == 14342 && attachee.HasEquippedByName(4083))) // Lamia
        {
            attachee.FindItemByName(4083).Destroy();
            return(RunDefault);
        }

        if ((attachee.GetNameId() == 14342 && attachee.FindItemByName(4083) == null && RandomRange(1, 100) <= 50))
        {
            Utilities.create_item_in_inventory(4083, attachee);
            attachee.WieldBestInAllSlots();
        }

        if ((attachee.GetNameId() == 14295 && !attachee.D20Query(D20DispatcherKey.QUE_Critter_Is_Blinded))) // Basilisk
        {
            attachee.PendingSpellsToMemorized();
        }

        if ((attachee.GetNameId() == 14258)) // Guardian Vrock
        {
            SetGlobalVar(762, GetGlobalVar(762) + 1);
            if ((GetGlobalVar(762) >= 3))
            {
                var damage_dice = Dice.D8;
                AttachParticles("Mon-Vrock-Spores", attachee);
                foreach (var obj in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_CRITTERS))
                {
                    if ((obj.DistanceTo(attachee) <= 10 && obj.GetNameId() != 14258 && obj.GetNameId() != 14361))
                    {
                        obj.DealSpellDamage(attachee, DamageType.Poison, damage_dice, D20AttackPower.UNSPECIFIED, D20ActionType.CAST_SPELL, 261);
                        AttachParticles("Mon-Vrock-Spores-Hit", obj);
                    }
                }
            }
        }

        // damage_dice = dice_new( '1d8' )
        // game.particles( 'Mon-Vrock-Spores', attachee)
        // for obj in game.obj_list_vicinity(attachee.location,OLC_CRITTERS):
        // if (obj.distance_to(attachee) <= 10 and obj.name != 14258):
        // obj.damage( OBJ_HANDLE_NULL, D20DT_POISON, damage_dice, D20DAP_NORMAL)
        // obj.spell_damage( attachee, D20DT_POISON, damage_dice, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, 261 )
        // obj.condition_add_with_args( "Poisoned", 273 , 10)
        // obj.condition_add_with_args( 'sp-Vrock Spores', 273, 10, 0)
        // game.particles( 'Mon-Vrock-Spores-Hit', obj )
        // if ((attachee.name == 14259 or attachee.name == 14360) and game.random_range(1,3) <= 3):
        // create_item_in_inventory( 8909, attachee )
        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #7
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        if (attachee.GetMap() == 5005) // Moathouse Dungeon
        {
            foreach (var npc in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_NPC))
            {
                if ((new[] { 14066, 14067, 14078, 14079, 14080 }).Contains(npc.GetNameId()) && npc.GetLeader() == null && npc.GetScriptId(ObjScriptEvent.StartCombat) == 0)
                {
                    npc.SetScriptId(ObjScriptEvent.StartCombat, 75);
                }
            }
        }
        else if (attachee.GetMap() == 5066) // Temple level 1
        {
            foreach (var npc in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_NPC))
            {
                if (npc.GetLeader() == null && npc.GetScriptId(ObjScriptEvent.StartCombat) == 0)
                {
                    npc.SetScriptId(ObjScriptEvent.StartCombat, 2);
                }
            }
        }

        if ((GetGlobalVar(709) == 2 && attachee.GetMap() == 5005))
        {
            SetGlobalVar(709, 3);
            foreach (var obj in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_NPC))
            {
                if ((obj.GetNameId() == 14079 || obj.GetNameId() == 14080 || obj.GetNameId() == 14067 || obj.GetNameId() == 14078 || obj.GetNameId() == 14066))
                {
                    obj.TurnTowards(triggerer);
                    obj.Attack(triggerer);
                }
            }
        }

        if (attachee.GetMap() == 5066 && (!ScriptDaemon.get_f("j_ogre_temple_1"))) // temple level 1 - gnolls near southern stairs
        {
            var(xx, yy) = attachee.GetLocation();
            if ((Math.Pow((xx - 564), 2) + Math.Pow((yy - 599), 2)) < 200)
            {
                ScriptDaemon.set_f("j_ogre_temple_1");
                var xxp_min = 564;
                var xxp_o   = 564;
                foreach (var pc in PartyLeader.GetPartyMembers())
                {
                    var(xxp, yyp) = pc.GetLocation();
                    if (yyp >= 599)
                    {
                        if (xxp < xxp_min)
                        {
                            xxp_min = xxp;
                        }
                    }
                    else if (yyp < 599 && xxp >= 519 && xxp <= 546 && yyp >= 589)
                    {
                        if (xxp < xxp_o)
                        {
                            xxp_o = xxp;
                        }
                    }
                }

                var x_ogre = Math.Min(xxp_min, xxp_o) - 20;
                x_ogre = Math.Max(507, x_ogre);
                foreach (var npc in ObjList.ListVicinity(new locXY(507, 603), ObjectListFilter.OLC_NPC))
                {
                    if (npc.GetNameId() == 14448 && npc.GetLeader() == null && !npc.IsUnconscious())
                    {
                        npc.Move(new locXY(x_ogre, 601), 0, 0);
                        npc.Attack(SelectedPartyLeader);
                    }
                }
            }
        }

        // THIS IS USED FOR BREAK FREE
        var found_nearby = 0;

        foreach (var obj in PartyLeader.GetPartyMembers())
        {
            if ((obj.DistanceTo(attachee) <= 3 && obj.GetStat(Stat.hp_current) >= -9))
            {
                found_nearby = 1;
            }
        }

        if (found_nearby == 0)
        {
            while ((attachee.FindItemByName(8903) != null))
            {
                attachee.FindItemByName(8903).Destroy();
            }
        }

        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #8
0
    public bool OnStartCombat(GameObject attachee, GameObject triggerer, bool generated_from_timed_event_call)
    {
        if (attachee.GetBaseStat(Stat.dexterity) == -30)
        {
            // Beacon object - skip its turn in case it somehow survives
            attachee.Destroy();
            return(SkipDefault);
        }

        if (GetGlobalFlag(403) && GetGlobalFlag(405))
        {
            attachee.FloatMesFileLine("mes/script_activated.mes", 15, TextFloaterColor.Red);
        }

        var ggv400 = GetGlobalVar(400);
        var ggv401 = GetGlobalVar(401);
        var pad3   = attachee.GetInt(obj_f.npc_pad_i_3);

        if ((ggv400 & (1)) != 0)
        {
            if (attachee.IsUnconscious() && (pad3 & (2)) == 0)
            {
                // Troop knocked unconscious - mark him as such and increase the KOed counter
                pad3 |= 2;
                attachee.SetInt(obj_f.npc_pad_i_3, pad3);
                ggv401 += 1 << 7;
                SetGlobalVar(401, ggv401);
            }
            else if ((pad3 & (2)) != 0 && !attachee.IsUnconscious())
            {
                // Attachee has contributed to unconscious count, but is no longer unconscious
                // E.g. healed
                pad3 &= ~(2);
                if (((ggv401 >> 7) & 15) > 0)
                {
                    ggv401 -= (1 << 7);
                }

                attachee.SetInt(obj_f.npc_pad_i_3, pad3);
                SetGlobalVar(401, ggv401);
            }

            if ((new[] { 14074, 14075, 14076, 14077 }).Contains(attachee.GetNameId()))
            {
                // The "Call Lareth" section
                // Calculates how many troops are down etc. and decides whether to call Lareth
                GameObject seleucas     = null;
                GameObject lareth_sarge = null;
                foreach (var obj1 in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_NPC))
                {
                    if (obj1.GetNameId() == 14077)
                    {
                        seleucas = obj1;
                    }
                    else if (obj1.GetNameId() == 14076)
                    {
                        lareth_sarge = obj1;
                    }
                }

                bool seleucas_down;
                if ((seleucas != null && seleucas.IsUnconscious()) || (ggv400 & (2)) != 0 || (seleucas.GetLeader() != null))
                {
                    seleucas_down = true;
                }
                else
                {
                    seleucas_down = false;
                }

                bool lareth_sarge_down;
                if ((lareth_sarge != null && lareth_sarge.IsUnconscious()))
                {
                    lareth_sarge_down = true;
                }
                else
                {
                    lareth_sarge_down = false;
                }

                var troops_down        = ((ggv401 >> 3) & 15) + ((ggv401 >> 7) & 15);
                var should_call_lareth = false;
                if (seleucas_down && (troops_down >= 2)) // Seleucas + 1 other troop
                {
                    should_call_lareth = true;
                }
                else if (seleucas_down && lareth_sarge_down) // Seleucas + Sergeant
                {
                    should_call_lareth = true;
                }
                else if (troops_down >= 2)
                {
                    should_call_lareth = true;
                }

                if (should_call_lareth)
                {
                    if ((ggv400 & (0x4 + (0x20))) == 0)
                    {
                        // Lareth has not been called upon
                        // And have not initiated combat with Lareth
                        if (seleucas_down && !attachee.IsUnconscious() && (attachee.GetLeader() == null))
                        {
                            // Seleucas is down - the soldier calls Lareth
                            var temppp = attachee.GetScriptId(ObjScriptEvent.Dialog);
                            attachee.SetScriptId(ObjScriptEvent.Dialog, 450);
                            attachee.FloatLine(15001, triggerer);
                            attachee.SetScriptId(ObjScriptEvent.Dialog, temppp);
                            ggv400 |= 0x4;
                            SetGlobalVar(400, ggv400);
                        }
                        else if (!seleucas_down)
                        {
                            // Seleucas is alive - Seleucas calls Lareth
                            seleucas.FloatLine(15000, triggerer);
                            ggv400 |= 0x4;
                            SetGlobalVar(400, ggv400);
                        }
                    }
                    else if ((ggv400 & 0x28) == 0)
                    {
                        var lareth = Utilities.find_npc_near(attachee, 8002);
                        if (lareth != null && !lareth.IsUnconscious())
                        {
                            // if can_see_party(lareth) == 0:
                            lareth.SetInt(obj_f.critter_strategy, 81);        // Lareth's "Join the Fray" strategy - start with shield of faith, then target hurt friendly, heal, and commence attack
                            lareth.SetScriptId(ObjScriptEvent.EndCombat, 60); // san_end_combat
                            lareth.Move(new locXY(476, 546), -60, 10);        // This is to decrease the chances of Lareth skipping his turn
                            var closest_party_member = SelectedPartyLeader;
                            foreach (var pcc in GameSystems.Party.PartyMembers)
                            {
                                if (pcc.DistanceTo(attachee) < closest_party_member.DistanceTo(attachee))
                                {
                                    closest_party_member = pcc;
                                }
                            }

                            lareth.CastSpell(WellKnownSpells.ShieldOfFaith, lareth);
                            lareth.Attack(closest_party_member);
                            var init_current = -100;
                            foreach (var pc in GameSystems.Party.PartyMembers)
                            {
                                if (pc.GetInitiative() < attachee.GetInitiative() && (pc.GetInitiative() - 2) > init_current)
                                {
                                    init_current = pc.GetInitiative() - 2;
                                }
                            }

                            lareth.SetInitiative(init_current); // make sure he gets to act on the same round
                            ggv400 |= 8;
                            SetGlobalVar(400, ggv400);
                        }
                    }
                }
            }

            if (attachee.GetLeader() != null && (pad3 & 0x4) == 0)
            {
                // Attachee charmed
                pad3 |= 0x4;
                attachee.SetInt(obj_f.npc_pad_i_3, pad3);
                ggv401 += (1 << 11);
                SetGlobalVar(401, ggv401);
            }
        }

        // Copied from script 310 :	#
        // THIS IS USED FOR BREAK FREE
        while ((attachee.FindItemByName(8903) != null))
        {
            attachee.FindItemByName(8903).Destroy();
        }

        if ((attachee.D20Query(D20DispatcherKey.QUE_Is_BreakFree_Possible))) // workaround no longer necessary!
        {
            return(RunDefault);
        }

        // create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        // Wake up from Sleep Scripting	#
        var a123 = attachee.ItemWornAt(EquipSlot.WeaponPrimary).GetInt(obj_f.weapon_type);

        if ((new[] { 14, 17, 46, 48, 68 }).Contains(a123)) // (Is archer)
        {
            // 14 - light crossbow
            // 17 - heavy crossbow
            // 46 - shortbow
            // 48 - longbow
            // 68 - repeating crossbow
            if (!generated_from_timed_event_call && !attachee.IsUnconscious() && !attachee.D20Query(D20DispatcherKey.QUE_Prone) && attachee.GetLeader() == null)
            {
                var player_in_obscuring_mist = 0;
                var grease_detected          = 0;
                var should_wake_up_comrade   = 0;
                // 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;
                    }
                }

                foreach (var spell_obj in ObjList.ListCone(closest_pc_1, ObjectListFilter.OLC_GENERIC, 30, 0, 360))
                {
                    // Check for active OBSCURING MIST spell objects
                    if (spell_obj.GetInt(obj_f.secretdoor_dc) == 333 + (1 << 15) && spell_obj.DistanceTo(closest_pc_1) <= 17.5f)
                    {
                        player_in_obscuring_mist = 1;
                    }
                }

                foreach (var spell_obj in ObjList.ListCone(closest_pc_1, 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 = 1;
                        var grease_obj = spell_obj;
                    }
                }

                // Scripting for approaching sleeping friend
                if (player_in_obscuring_mist == 1 || RandomRange(0, 1) == 0)
                {
                    // Player staying back in Obscuring Mist - thus it's more useful to use the archer to wake someone up
                    // Otherwise, 50% chance
                    should_wake_up_comrade = 1;
                }

                if (closest_pc_1.DistanceTo(attachee) <= 8)
                {
                    // Player is close - Attachee will probably get hit trying to approach friend, so abort
                    should_wake_up_comrade = 0;
                }

                if (player_in_obscuring_mist == 1 && RandomRange(1, 12) == 1)
                {
                    // Player Cast Obscuring Mist -
                    // Float a comment about not being able to see the player (1 in 12 chance)
                    if (attachee.GetScriptId(ObjScriptEvent.Dialog) == 0)
                    {
                        attachee.SetScriptId(ObjScriptEvent.Dialog, 450);
                    }

                    attachee.FloatLine(16520 + RandomRange(0, 2), attachee);
                }
            }
        }
        else
        {
            Livonya.tag_strategy(attachee);
            if ((new[] { 37, 41, 43, 44, 61 }).Contains(a123))
            {
                // Reach Weapons
            }
            else
            {
                SetGlobalVar(499, 19);
                Livonya.get_melee_strategy(attachee);
            }
        }

        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #9
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        if (GetGlobalFlag(403) && GetGlobalFlag(405))
        {
            attachee.FloatMesFileLine("mes/script_activated.mes", 15, TextFloaterColor.Red);
        }

        if (((new[] { 14262, 14191, 14691 }).Contains(attachee.GetNameId()))) // trolls
        {
            if ((attachee.AddCondition("Rend")))
            {
                Logger.Info("Added Rend");
            }
        }

        if (((new[] { 14050, 14391, 14352, 14406, 14408, 14610, 14994 }).Contains(attachee.GetNameId()))) // wolves
        {
            if ((attachee.AddCondition("Tripping Bite")))
            {
                Logger.Info("Added Tripping Bite");
            }
        }

        if (((attachee.GetNameId() == 14238 || attachee.GetNameId() == 14697 || attachee.GetNameId() == 14573 || attachee.GetNameId() == 14824) && (!attachee.HasEquippedByName(4099) || !attachee.HasEquippedByName(4100))))
        {
            // Ettin
            attachee.WieldBestInAllSlots();
        }
        // game.new_sid = 0
        else if ((attachee.GetNameId() == 14336 && (!attachee.HasEquippedByName(4081) || !attachee.HasEquippedByName(4126))))
        {
            // Elven Ranger
            attachee.WieldBestInAllSlots();
            attachee.WieldBestInAllSlots();
        }
        // game.new_sid = 0
        else if ((attachee.GetNameId() == 14357 && (!attachee.HasEquippedByName(4156) || !attachee.HasEquippedByName(4159))))
        {
            // Grank's Bandit
            attachee.WieldBestInAllSlots();
        }
        // game.new_sid = 0
        else if ((attachee.GetNameId() == 14747 && (!attachee.HasEquippedByName(4040) || !attachee.HasEquippedByName(4159))))
        {
            // Half Orc Assassin
            attachee.WieldBestInAllSlots();
        }
        else if (attachee.GetNameId() == 14057 && attachee.GetMap() == 5002)
        {
            // Giant Frogs of the Moathouse
            foreach (var obj in ObjList.ListVicinity(new locXY(492, 522), ObjectListFilter.OLC_NPC))
            {
                if (obj.GetNameId() == 14057 && obj.GetLeader() == null)
                {
                    obj.Attack(SelectedPartyLeader);
                }
            }

            foreach (var obj in ObjList.ListVicinity(new locXY(470, 522), ObjectListFilter.OLC_NPC))
            {
                if (obj.GetNameId() == 14057 && obj.GetLeader() == null)
                {
                    obj.Attack(SelectedPartyLeader);
                }
            }

            foreach (var obj in ObjList.ListVicinity(new locXY(473, 506), ObjectListFilter.OLC_NPC))
            {
                if (obj.GetNameId() == 14057 && obj.GetLeader() == null)
                {
                    obj.Attack(SelectedPartyLeader);
                }
            }
        }
        else if (attachee.GetNameId() == 14337 && attachee.GetMap() == 5066)
        {
            // Earth Temple Guards
            if (attachee.GetMap() == 5066) // temple level 1 - guards near the corridor of bones - call in Earth Temple Fighters
            {
                var(xx, yy) = attachee.GetLocation();
                if ((Math.Pow((xx - 441), 2) + Math.Pow((yy - 504), 2)) < 200)
                {
                    foreach (var npc in ObjList.ListVicinity(new locXY(441, 504), ObjectListFilter.OLC_NPC))
                    {
                        if ((new[] { 14337, 14338 }).Contains(npc.GetNameId()) && npc.GetLeader() == null && !npc.IsUnconscious())
                        {
                            var(xx2, yy2) = npc.GetLocation();
                            if ((Math.Pow((xx2 - 441), 2) + Math.Pow((yy2 - 504), 2)) < 300)
                            {
                                // print str(xx) + " " + str(yy) + "  " + str(xx2) + " " + str(yy2)
                                if (npc.GetScriptId(ObjScriptEvent.StartCombat) == 0)
                                {
                                    npc.SetScriptId(ObjScriptEvent.StartCombat, 2);
                                }

                                npc.Attack(SelectedPartyLeader);
                            }
                        }
                    }
                }
            }
        }
        else if (attachee.GetNameId() == 14338) // Earth Temple Fighters
        {
            if (attachee.ItemWornAt(EquipSlot.WeaponPrimary) == null)
            {
                attachee.WieldBestInAllSlots();
            }
        }
        else if (attachee.GetNameId() == 14888) // siren cultist screaching
        {
            Sound(4188, 1);
        }

        // ALSO, THIS IS USED FOR BREAK FREE
        while ((attachee.FindItemByName(8903) != null))
        {
            attachee.FindItemByName(8903).Destroy();
        }

        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        if (attachee.GetLeader() != null) // Don't wanna f**k up charmed enemies
        {
            return(RunDefault);
        }

        // Special scripting		#
        if (attachee.GetNameId() == 14262 || attachee.GetNameId() == 14195 || attachee.GetNameId() == 14343 || attachee.GetNameId() == 14224 || attachee.GetNameId() == 14375)
        {
            // 14262 - Troll, 14195 - Oohlgrist, 14343 - Hydra, 14224 - Hydra Keeper
            // 14375 - Water Snake
            Logger.Info("{0}", "strategy chosen was " + attachee.GetInt(obj_f.critter_strategy).ToString());
        }
        else if (attachee.GetNameId() == 8091) // Belsornig
        {
            var goodguys    = 0;
            var nonevilguys = 0;
            foreach (var dude in GameSystems.Party.PartyMembers)
            {
                if (dude.GetAlignment().IsGood())
                {
                    goodguys = goodguys + 1;
                }

                if ((dude.GetAlignment() & (Alignment.NEUTRAL_EVIL)) == 0)
                {
                    nonevilguys = nonevilguys + 1;
                }
            }

            if (goodguys <= 1 || (nonevilguys) <= 3)
            {
                attachee.SetInt(obj_f.critter_strategy, 74); // Belsornig AI without Unholy Blight
            }
        }
        else if (attachee.GetNameId() == 14888) // Siren Cultist
        {
            if (Utilities.party_closest(attachee, mode_select: 0) == null)
            {
                attachee.SetInt(obj_f.critter_strategy, 573); // No PCs left to charm; charming NPCs causes them to be permanently hostile, essentially killing them unless charmed back or dominated, so I'll switch to an alternative spell list here
            }
            else
            {
                attachee.SetInt(obj_f.critter_strategy, 572); // the charm tactic
            }
        }
        else if ((new[] { 14095, 14128, 14129 }).Contains(attachee.GetNameId()) && attachee.GetMap() == 5066)
        {
            var(xx, yy) = attachee.GetLocation();
            if ((yy <= 548 && yy >= 540 && xx >= 416 && xx <= 425) || (yy <= 540 && yy >= 530 && xx >= 421 && xx <= 425) || (xx <= 419 && yy <= 533 && yy >= 518)) // Room to the west of the harpy corridor
            {
                if (attachee.D20Query(D20DispatcherKey.QUE_Turned))
                {
                    foreach (var obj in ObjList.ListVicinity(attachee.GetLocation(), ObjectListFilter.OLC_PORTAL))
                    {
                        obj.SetObjectFlag(ObjectFlag.OFF);
                    }
                }
            }
        }

        // Summoned Creaute/ Spiritual Weapon / Warded PC scripting	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }
コード例 #10
0
    public override bool OnStartCombat(GameObject attachee, GameObject triggerer)
    {
        if (attachee.GetMap() == 5067 && (new[] { 14174, 14175, 14177, 13002 }).Contains(attachee.GetNameId())) // ToEE level 2 - big bugbear room scripting
        {
            var(xx, yy) = attachee.GetLocation();
            if (xx >= 416 && xx <= 434 && yy >= 350 && yy <= 398) // big bugbear room
            {
                if (ScriptDaemon.get_v("bugbear_room_timevent_count") < 5)
                {
                    StartTimer(750, () => bugbear_room_increment_turn_counter(ScriptDaemon.get_v("bugbear_room_turn_counter") + 1)); // reset flag in 750ms; in this version, time is frozen, so it will only take place next turn
                    ScriptDaemon.inc_v("bugbear_room_timevent_count");
                }

                var pcs_in_east_hallway        = 0;
                var pcs_in_south_hallway       = 0;
                var pcs_in_inner_south_hallway = 0;
                var yyp_east_max  = 355;
                var xxp_inner_max = 416;
                foreach (var obj in PartyLeader.GetPartyMembers())
                {
                    var(xxp, yyp) = obj.GetLocation();
                    if (yyp >= 355 && yyp <= 413 && xxp >= 405 && xxp <= 415 && !obj.IsUnconscious())
                    {
                        pcs_in_east_hallway += 1;
                        if (yyp > yyp_east_max)
                        {
                            yyp_east_max = yyp;
                        }
                    }

                    if (yyp >= 414 && yyp <= 422 && xxp >= 405 && xxp <= 455)
                    {
                        pcs_in_south_hallway += 1;
                    }

                    if (yyp >= 391 && yyp <= 413 && xxp >= 416 && xxp <= 455)
                    {
                        pcs_in_inner_south_hallway += 1;
                        if (xxp > xxp_inner_max)
                        {
                            xxp_inner_max = xxp;
                        }
                    }
                }

                var bugbears_near_door           = new List <GameObject>();
                var bugbears_near_south_entrance = new List <GameObject>();
                foreach (var bugbear_dude in ObjList.ListVicinity(new locXY(416, 359), ObjectListFilter.OLC_NPC))
                {
                    if ((new[] { 14174, 14175, 14177 }).Contains(bugbear_dude.GetNameId()) && Utilities.willing_and_capable(bugbear_dude))
                    {
                        var(xxb, yyb) = bugbear_dude.GetLocation();
                        if (xxb >= 416 && xxb <= 434 && yyb >= 350 && yyb < 372)
                        {
                            bugbears_near_door.Add(bugbear_dude);
                        }
                    }
                }

                // TODO - fear
                foreach (var bugbear_dude in ObjList.ListVicinity(new locXY(425, 383), ObjectListFilter.OLC_NPC))
                {
                    if ((new[] { 14174, 14175, 14177 }).Contains(bugbear_dude.GetNameId()) && Utilities.willing_and_capable(bugbear_dude))
                    {
                        var(xxb, yyb) = bugbear_dude.GetLocation();
                        if (xxb >= 416 && xxb <= 434 && yyb >= 372 && yyb <= 399)
                        {
                            bugbears_near_south_entrance.Add(bugbear_dude);
                        }
                    }
                }

                if (pcs_in_inner_south_hallway == 0 && pcs_in_south_hallway == 0 && pcs_in_east_hallway > 0)
                {
                    // PCs in east hallway only - take 3 turns to get there
                    if (ScriptDaemon.get_v("bugbear_room_turn_counter") >= 3)
                    {
                        int xxb_base, yyb_base;
                        if (yyp_east_max <= 395)
                        {
                            yyb_base = yyp_east_max + 20;
                            xxb_base = 406;
                        }
                        else
                        {
                            xxb_base = 416;
                            yyb_base = 415;
                        }

                        var bb_index          = 0;
                        var bb_x_offset_array = new[] { 0, 0, 1, 1, 2, 2, -1, -1 };
                        var bb_y_offset_array = new[] { 0, 1, 0, 1, 0, 1, 0, 1 };
                        foreach (var bugbear_dude in bugbears_near_south_entrance)
                        {
                            if (bugbear_dude != attachee && bb_index <= 7)
                            {
                                bugbear_dude.Move(new locXY(xxb_base + bb_x_offset_array[bb_index], yyb_base + bb_y_offset_array[bb_index]), 0f, 0f);
                                bugbear_dude.Attack(SelectedPartyLeader);
                                bb_index += 1;
                            }
                        }
                    }
                }
                else if (pcs_in_inner_south_hallway > 0 && pcs_in_south_hallway == 0 && pcs_in_east_hallway == 0)
                {
                    // PCs in inner south hallway only - take 3 turns to reach
                    if (ScriptDaemon.get_v("bugbear_room_turn_counter") >= 3)
                    {
                        int   xxb_base;
                        int   yyb_base;
                        int[] bb_x_offset_array;
                        int[] bb_y_offset_array;
                        if (xxp_inner_max <= 440)
                        {
                            xxb_base          = xxp_inner_max + 15;
                            yyb_base          = 406;
                            bb_x_offset_array = new[] { 0, 0, 1, 1, 2, 2, 0, 0 };
                            bb_y_offset_array = new[] { 0, -1, 0, -1, 0, -1, 1, 2 };
                        }
                        else
                        {
                            xxb_base          = 450;
                            yyb_base          = 415;
                            bb_x_offset_array = new[] { 0, 0, 1, 1, 2, 2, -1, -1 };
                            bb_y_offset_array = new[] { 0, 1, 0, 1, 0, 1, 0, 1 };
                        }

                        var bb_index = 0;
                        foreach (var bugbear_dude in bugbears_near_door)
                        {
                            if (bugbear_dude != attachee && bb_index <= 7)
                            {
                                bugbear_dude.Move(new locXY(xxb_base + bb_x_offset_array[bb_index], yyb_base + bb_y_offset_array[bb_index]), 0f, 0f);
                                bugbear_dude.Attack(SelectedPartyLeader);
                                bb_index += 1;
                            }
                        }
                    }
                }
            }
        }

        // THIS IS USED FOR BREAK FREE
        // found_nearby = 0
        // for obj in game.party[0].group_list():
        // if (obj.distance_to(attachee) <= 3 and obj.stat_level_get(stat_hp_current) >= -9):
        // found_nearby = 1
        // if found_nearby == 0:
        // while(attachee.item_find(8903) != OBJ_HANDLE_NULL):
        // attachee.item_find(8903).destroy()
        // if (attachee.d20_query(Q_Is_BreakFree_Possible)): # workaround no longer necessary!
        // create_item_in_inventory( 8903, attachee )
        // attachee.d20_send_signal(S_BreakFree)
        // Spiritual Weapon Shenanigens	#
        CombatStandardRoutines.Spiritual_Weapon_Begone(attachee);
        return(RunDefault);
    }