예제 #1
0
        private void MoveMissile(MissileInfo missile, float timelapseSeconds)
        {
            bool collision;

            Move(
                missile.X,
                missile.Y,
                missile.Distance,
                missile.Speed,
                missile.Heading,
                missile.Range,
                timelapseSeconds,
                out var missileX,
                out var missileY,
                out var missileDistance,
                out collision
                );
            missile.X        = missileX;
            missile.Y        = missileY;
            missile.Distance = missileDistance;
            if (collision)
            {
                missile.Status = MissileStatus.ExplodingDirect;
                missile.Speed  = 0.0f;
            }
        }
예제 #2
0
        private void ApplyBotAction(BotInfo bot, GetActionResponse action)
        {
            var now = _provider.UtcNow;
            var secondsSinceUpdate = (float)(now - bot.LastStatusUpdate).TotalSeconds;

            bot.LastStatusUpdate = now;

            // reduce reload time if any is active
            if (bot.ReloadCoolDown > 0)
            {
                bot.ReloadCoolDown = MathF.Max(0.0f, bot.ReloadCoolDown - secondsSinceUpdate);
            }

            // check if any actions need to be applied
            if (action is null)
            {
                // bot didn't respond with an action; consider it dead
                bot.Status = BotStatus.Dead;
                bot.TimeOfDeathGameTurn = GameSession.CurrentGameTurn;
                AddMessage($"{bot.Name} (R{bot.Index}) was disqualified by lack of action");
                return;
            }

            // update bot state
            bot.InternalState = action.BotState;

            // update speed and heading
            bot.TargetSpeed   = GameMath.MinMax(0.0f, action.Speed ?? bot.TargetSpeed, bot.MaxSpeed);
            bot.TargetHeading = GameMath.NormalizeAngle(action.Heading ?? bot.TargetHeading);

            // fire missile if requested and possible
            if ((action.FireMissileHeading.HasValue || action.FireMissileDistance.HasValue) && (bot.ReloadCoolDown == 0.0f))
            {
                // update bot state
                ++bot.TotalMissileFiredCount;
                bot.ReloadCoolDown = bot.MissileReloadCooldown;

                // add missile
                var missile = new MissileInfo {
                    Id      = $"{bot.Id}:M{bot.TotalMissileFiredCount}",
                    BotId   = bot.Id,
                    Status  = MissileStatus.Flying,
                    X       = bot.X,
                    Y       = bot.Y,
                    Speed   = bot.MissileVelocity,
                    Heading = GameMath.NormalizeAngle(action.FireMissileHeading ?? bot.Heading),
                    Range   = GameMath.MinMax(0.0f, action.FireMissileDistance ?? bot.MissileRange, bot.MissileRange),
                    DirectHitDamageBonus = bot.MissileDirectHitDamageBonus,
                    NearHitDamageBonus   = bot.MissileNearHitDamageBonus,
                    FarHitDamageBonus    = bot.MissileFarHitDamageBonus
                };
                GameSession.Missiles.Add(missile);
            }
        }
예제 #3
0
        private void AssessMissileDamage(MissileInfo missile)
        {
            FindBotsByDistance(missile.X, missile.Y, (bot, distance) => {
                // compute damage dealt by missile
                float damage      = 0.0f;
                string damageType = null;
                switch (missile.Status)
                {
                case MissileStatus.ExplodingDirect:
                    if (distance <= GameSession.DirectHitRange)
                    {
                        damage     = bot.DirectHitDamage + missile.DirectHitDamageBonus;
                        damageType = "direct";
                    }
                    break;

                case MissileStatus.ExplodingNear:
                    if (distance <= GameSession.NearHitRange)
                    {
                        damage     = bot.NearHitDamage + missile.NearHitDamageBonus;
                        damageType = "near";
                    }
                    break;

                case MissileStatus.ExplodingFar:
                    if (distance <= GameSession.FarHitRange)
                    {
                        damage     = bot.FarHitDamage + missile.FarHitDamageBonus;
                        damageType = "far";
                    }
                    break;
                }

                // check if any damage was dealt
                if (damage == 0.0f)
                {
                    // stop enumerating more bots since they will be further away
                    return(false);
                }

                // record damage dealt
                var from = GameSession.Bots.FirstOrDefault(fromBot => fromBot.Id == missile.BotId);
                if (from != null)
                {
                    from.TotalDamageDealt += damage;
                    ++from.TotalMissileHitCount;

                    // check if bot was killed
                    if (Damage(bot, damage))
                    {
                        ++from.TotalKills;

                        // check if bot inflicted damage to itself
                        if (bot.Id == from.Id)
                        {
                            AddMessage($"{bot.Name} (R{bot.Index}) killed itself");
                        }
                        else
                        {
                            AddMessage($"{bot.Name} (R{bot.Index}) was killed by {from.Name} (R{from.Index})");
                        }
                    }
                    else
                    {
                        // check if bot inflicted damage to itself
                        if (bot.Id == from.Id)
                        {
                            AddMessage($"{bot.Name} (R{bot.Index}) caused {damage:N0} {damageType} damage to itself");
                        }
                        else
                        {
                            AddMessage($"{bot.Name} (R{bot.Index}) received {damage:N0} {damageType} damage from {from.Name} (R{from.Index})");
                        }
                    }
                }
                return(true);
            });
        }