예제 #1
0
        public override void Attack(Point position, Point targetPosition, IDestroyableObject target)
        {
            base.Attack(position, targetPosition, target);

            var currentHitChance = CalculateHitChance(hitChance);

            if (!RandomHelper.CheckChance(currentHitChance))
            {
                CurrentGame.Journal.Write(new AttackMissMessage(this, target), this);
                return;
            }

            if (RandomHelper.CheckChance(target.DodgeChance))
            {
                CurrentGame.Journal.Write(new AttackDodgedMessage(this, target));
                return;
            }

            var attackDirection = Point.GetAdjustedPointRelativeDirection(targetPosition, position);

            if (!attackDirection.HasValue)
            {
                throw new ApplicationException("Can only attack adjusted target");
            }

            foreach (var damageValue in attackDamage)
            {
                var value = RandomHelper.GetRandomValue(damageValue.MinValue, damageValue.MaxValue);
                target.MeleeDamage(targetPosition, attackDirection.Value, value, damageValue.Element);
                CurrentGame.Journal.Write(new DealDamageMessage(this, target, value, damageValue.Element), this);
            }
        }
예제 #2
0
        public bool Update(IDestroyableObject owner, Point position)
        {
            if (burnTime >= burnBeforeExtinguishCheck)
            {
                if (RandomHelper.CheckChance((int)Math.Round(owner.GetSelfExtinguishChance())))
                {
                    return(false);
                }
            }

            burnTime++;

            var damage = Temperature.GetTemperatureDamage(ConfigurationManager.Current.Physics.TemperatureConfiguration, burningTemperature, out _);

            if (damage == 0)
            {
                return(true);
            }

            CurrentGame.Journal.Write(new BurningDamageMessage(owner, damage), owner);
            owner.Damage(position, damage, Element.Fire);

            var cell            = CurrentGame.Map.GetCell(position);
            var temperatureDiff = cell.Temperature() - burningTemperature;

            if (temperatureDiff > 0)
            {
                var cellTemperatureIncrement         = Math.Min(temperatureDiff, CellTemperatureIncreaseMax);
                cell.Environment.Cast().Temperature += cellTemperatureIncrement;
            }

            return(true);
        }
예제 #3
0
        public IMapObject CreateWall(int torchChance)
        {
            if (RandomHelper.CheckChance(torchChance))
            {
                return(CreateTorchWall());
            }

            return(CreateWall());
        }
예제 #4
0
        public IMapObject CreateWall()
        {
            if (RandomHelper.CheckChance(SpikedWallChance))
            {
                return(new SpikedDungeonWall());
            }

            return(new DungeonWall());
        }
예제 #5
0
        private void CheckParalyzed(int damage)
        {
            var chance = (int)Math.Round(damage * ParalyzedChanceMultiplier);

            if (RandomHelper.CheckChance(chance))
            {
                Statuses.Add(new ParalyzedObjectStatus());
            }
        }
예제 #6
0
        private void CheckFrozen(int damage)
        {
            var chance = (int)Math.Round(damage * FrozenChanceMultiplier);

            if (RandomHelper.CheckChance(chance))
            {
                Statuses.Add(new FrozenObjectStatus());
            }
        }
예제 #7
0
        protected override int TryBlockMeleeDamage(Direction damageDirection, int damage, Element element)
        {
            if (!RandomHelper.CheckChance(configuration.ShieldBlockChance))
            {
                return(damage);
            }

            var blockedDamage = Math.Min(configuration.ShieldBlocksDamage, damage);

            if (blockedDamage == 0)
            {
                return(damage);
            }

            CurrentGame.Journal.Write(new ShieldBlockedDamageMessage(this, blockedDamage, element));
            return(damage - blockedDamage);
        }
예제 #8
0
        public override bool Use(GameCore <Player> game)
        {
            var chanceToRead = GetChanceToRead(game.Player);

            if (RandomHelper.CheckChance(chanceToRead))
            {
                return(base.Use(game));
            }

            game.Journal.Write(new FailedToUseScrollMessage());
            game.Player.Damage(CurrentGame.PlayerPosition, MagicDamageOnFailedScroll, Element.Magic);
            game.Journal.Write(new EnvironmentDamageMessage(game.Player, MagicDamageOnFailedScroll, Element.Magic));
            var environment = (GameEnvironment)game.Map.GetCell(game.PlayerPosition).Environment;

            environment.MagicDisturbanceLevel += DisturbanceIncrementOnFailedScroll;
            return(false);
        }
예제 #9
0
        protected override bool Perform(GameCore <Player> game, out Point newPosition)
        {
            newPosition = game.PlayerPosition;

            if (game.Player.Statuses.Contains(ParalyzedObjectStatus.StatusType))
            {
                game.Journal.Write(new ParalyzedMessage());
                return(true);
            }

            if (game.Map.GetCell(game.PlayerPosition).Objects.Any(obj => obj.BlocksAttack))
            {
                return(true);
            }

            var targetPoint = Point.GetPointInDirection(game.PlayerPosition, game.Player.Direction);
            var targetCell  = game.Map.TryGetCell(targetPoint);

            if (targetCell == null)
            {
                return(true);
            }

            if (targetCell.Objects.Any(obj => obj.BlocksAttack))
            {
                return(true);
            }

            var possibleTargets = targetCell.Objects.OfType <IDestroyableObject>().ToArray();

            var target = GetAttackTarget(possibleTargets);

            if (target == null)
            {
                return(true);
            }

            if (game.Player.Stamina < StaminaToAttack)
            {
                game.Journal.Write(new NotEnoughStaminaMessage());
                return(true);
            }

            game.Player.Stamina -= StaminaToAttack;

            var holdableItem = useRightHand ? game.Player.Equipment.RightHandItem : game.Player.Equipment.LeftHandItem;

            if (!(holdableItem is IWeaponItem weapon))
            {
                game.Journal.Write(new CantAttackWithItemMessage(holdableItem));
                return(false);
            }

            var accuracy = weapon.Accuracy;

            accuracy += game.Player.AccuracyBonus;
            if (!RandomHelper.CheckChance(accuracy))
            {
                game.Journal.Write(new AttackMissMessage(game.Player, target));
                return(true);
            }

            if (RandomHelper.CheckChance(target.DodgeChance))
            {
                game.Journal.Write(new AttackDodgedMessage(game.Player, target));
                return(true);
            }

            var attackDirection = Point.GetAdjustedPointRelativeDirection(targetPoint, game.PlayerPosition);

            if (attackDirection == null)
            {
                throw new ApplicationException("Can only attack adjusted target");
            }

            var damage = GenerateDamage(game.Player, weapon);

            foreach (var damageValue in damage)
            {
                target.MeleeDamage(targetPoint, attackDirection.Value, damageValue.Value, damageValue.Key);
                game.Journal.Write(new DealDamageMessage(game.Player, target, damageValue.Value, damageValue.Key));
            }

            return(true);
        }