Пример #1
0
        public override void Execute()
        {
            RetCode rc;

            Debug.Assert(DobjArtifact != null || DobjMonster != null);

            if (!BlastSpell && ActorMonster.Weapon <= 0)
            {
                PrintMustFirstReadyWeapon();

                NextState = Globals.CreateInstance <IStartState>();

                goto Cleanup;
            }

            if (DobjMonster != null)
            {
                ProcessEvents(EventType.BeforeAttackMonster);

                if (GotoCleanup)
                {
                    goto Cleanup;
                }

                if (!DobjMonster.IsAttackable(ActorMonster))
                {
                    PrintWhyAttack(DobjMonster);

                    NextState = Globals.CreateInstance <IStartState>();

                    goto Cleanup;
                }

                if (!CheckAttack && DobjMonster.Reaction != Friendliness.Enemy)
                {
                    gOut.Write("{0}Attack non-enemy (Y/N): ", Environment.NewLine);

                    Globals.Buf.Clear();

                    rc = Globals.In.ReadField(Globals.Buf, Constants.BufSize02, null, ' ', '\0', false, null, gEngine.ModifyCharToUpper, gEngine.IsCharYOrN, null);

                    Debug.Assert(gEngine.IsSuccess(rc));

                    if (Globals.Buf.Length == 0 || Globals.Buf[0] == 'N')
                    {
                        NextState = Globals.CreateInstance <IStartState>();

                        goto Cleanup;
                    }

                    CheckAttack = true;

                    gEngine.MonsterGetsAggravated(DobjMonster);
                }

                CombatSystem = Globals.CreateInstance <ICombatSystem>(x =>
                {
                    x.SetNextStateFunc = s => NextState = s;

                    x.OfMonster = ActorMonster;

                    x.DfMonster = DobjMonster;

                    x.MemberNumber = MemberNumber;

                    x.AttackNumber = AttackNumber;

                    x.BlastSpell = BlastSpell;

                    x.OmitSkillGains = !BlastSpell && !ShouldAllowSkillGains();
                });

                CombatSystem.ExecuteAttack();

                goto Cleanup;
            }

            ProcessEvents(EventType.BeforeAttackArtifact);

            if (GotoCleanup)
            {
                goto Cleanup;
            }

            DobjArtAc = null;

            if (!DobjArtifact.IsAttackable01(ref _dobjArtAc))
            {
                PrintWhyAttack(DobjArtifact);

                NextState = Globals.CreateInstance <IStartState>();

                goto Cleanup;
            }

            Debug.Assert(DobjArtAc != null);

            if (DobjArtAc.Type == ArtifactType.DeadBody)
            {
                if (BlastSpell)
                {
                    gOut.Print("{0}", gEngine.GetBlastDesc());
                }

                DobjArtifact.SetInLimbo();

                PrintHackToBits();

                goto Cleanup;
            }

            if (DobjArtAc.Type == ArtifactType.DisguisedMonster)
            {
                gEngine.RevealDisguisedMonster(ActorRoom, DobjArtifact);

                DisguisedMonster = gMDB[DobjArtAc.Field1];

                Debug.Assert(DisguisedMonster != null);

                RedirectCommand = null;

                if (BlastSpell)
                {
                    RedirectCommand = Globals.CreateInstance <IBlastCommand>(x =>
                    {
                        x.CastSpell = false;
                    });
                }
                else
                {
                    RedirectCommand = Globals.CreateInstance <IAttackCommand>();
                }

                CopyCommandData(RedirectCommand);

                RedirectCommand.Dobj = DisguisedMonster;

                NextState = RedirectCommand;

                goto Cleanup;
            }

            /*
             *      Damage it...
             */

            KeyArtifactUid = DobjArtAc.GetKeyUid();

            if (KeyArtifactUid == -2)
            {
                PrintAlreadyBrokeIt(DobjArtifact);

                goto Cleanup;
            }

            BreakageStrength = DobjArtAc.GetBreakageStrength();

            if (BreakageStrength < 1000)
            {
                gOut.Print("Nothing happens.");

                goto Cleanup;
            }

            BreakageDice = 0;

            BreakageSides = 0;

            if (BlastSpell)
            {
                if (Globals.IsRulesetVersion(5, 15, 25))
                {
                    BreakageDice = 1;

                    BreakageSides = 6;
                }
                else
                {
                    BreakageDice = 2;

                    BreakageSides = 5;
                }

                Globals.Buf.SetPrint("{0}", gEngine.GetBlastDesc());
            }
            else
            {
                ActorWeapon = gADB[ActorMonster.Weapon];

                Debug.Assert(ActorWeapon != null);

                ActorWeaponAc = ActorWeapon.GeneralWeapon;

                Debug.Assert(ActorWeaponAc != null);

                BreakageDice = ActorWeaponAc.Field3;

                BreakageSides = ActorWeaponAc.Field4;

                BuildWhamHitObj();
            }

            gOut.Write("{0}", Globals.Buf);

            BreakageDamage = gEngine.RollDice(BreakageDice, BreakageSides, 0);

            BreakageStrength -= BreakageDamage;

            if (BreakageStrength > 1000)
            {
                DobjArtAc.SetBreakageStrength(BreakageStrength);

                goto Cleanup;
            }

            /*
             *      Broken!
             */

            DobjArtAc.SetOpen(true);

            DobjArtAc.SetKeyUid(-2);

            DobjArtAc.Field4 = 0;

            DobjArtifact.Value = 0;

            rc = DobjArtifact.AddStateDesc(DobjArtifact.GetBrokenDesc());

            Debug.Assert(gEngine.IsSuccess(rc));

            BuildSmashesToPieces();

            if (DobjArtAc.Type == ArtifactType.InContainer)
            {
                SpilledArtifactList = DobjArtifact.GetContainedList(containerType: ContainerType.In);

                if (DobjArtifact.OnContainer != null && DobjArtifact.IsInContainerOpenedFromTop())
                {
                    SpilledArtifactList.AddRange(DobjArtifact.GetContainedList(containerType: ContainerType.On));
                }

                foreach (var artifact in SpilledArtifactList)
                {
                    artifact.SetInRoom(ActorRoom);
                }

                if (SpilledArtifactList.Count > 0)
                {
                    BuildContentsSpillToFloor();
                }

                DobjArtAc.Field3 = 0;
            }

            Globals.Buf.AppendFormat("!{0}", Environment.NewLine);

            gOut.Write("{0}", Globals.Buf);

Cleanup:

            if (NextState == null)
            {
                NextState = Globals.CreateInstance <IMonsterStartState>();
            }
        }