Пример #1
0
        /// <summary>
        /// Get the next move to use
        /// </summary>
        /// <param name="lastAttack">Was there an attack last go</param>
        /// <returns>The next art to use</returns>
        public IFightingArt GetNext(IFightingArt lastAttack)
        {
            var nextAttack = Arts.FirstOrDefault();

            try
            {
                if (lastAttack != null)
                {
                    if (string.IsNullOrWhiteSpace(lastAttack.RekkaKey) || lastAttack.RekkaPosition < 0)
                    {
                        var myIndex = Arts.ToList().IndexOf(lastAttack);
                        nextAttack = Arts.Skip(myIndex + 1).FirstOrDefault();
                    }
                    else
                    {
                        nextAttack = Arts.FirstOrDefault(art => !string.IsNullOrWhiteSpace(art.RekkaKey) &&
                                                         art.RekkaKey.Equals(lastAttack.RekkaKey) &&
                                                         art.RekkaPosition == lastAttack.RekkaPosition + 1);
                    }

                    if (nextAttack == null)
                    {
                        //just throwing to redefault
                        throw new Exception();
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingUtility.LogError(ex);
                nextAttack = Arts.FirstOrDefault();
            }

            return(nextAttack);
        }
Пример #2
0
 /// <summary>
 /// Is this art valid to be used at the moment
 /// </summary>
 /// <param name="actor">who's doing the hitting</param>
 /// <param name="victim">who's being hit</param>
 /// <returns>yea or nay</returns>
 public bool IsValid(IMobile actor, IMobile victim, ulong distance, IFightingArt lastAttack = null)
 {
     return(distance.IsBetweenOrEqual(DistanceRange.Low, DistanceRange.High) &&
            actor.CurrentHealth >= Health.Actor &&
            actor.CurrentStamina >= Stamina.Actor &&
            (lastAttack == null || (lastAttack.RekkaKey.Equals(RekkaKey) && lastAttack.RekkaPosition == RekkaPosition - 1)));
 }
Пример #3
0
        /// <summary>
        /// Make the output messaging
        /// </summary>
        /// <returns>actor, target, room</returns>
        private static Tuple <string, string, string> GetOutputStrings(IFightingArt attack, IMobile target, bool blocked, ReadinessState avoidanceType)
        {
            var targetGlyph      = target == null ? "a shadow" : "$T$";
            var actorTargetGlyph = target == null ? "your shadow" : "$T$";

            var verb    = !string.IsNullOrWhiteSpace(attack.ActionVerb) ? attack.ActionVerb : attack.Name;
            var subject = !string.IsNullOrWhiteSpace(attack.ActionSubject) ? attack.ActionSubject + " " : string.Empty;
            var obj     = !string.IsNullOrWhiteSpace(attack.ActionPredicate) ? "and " + attack.ActionPredicate + " " : string.Empty;

            string toOrigin = string.Format("$A$ {0}s {3}{2}{1}.", verb, targetGlyph, obj, subject);
            string toActor  = string.Format("You {0} {3}{2}{1}.", verb, actorTargetGlyph, obj, subject);
            string toTarget = "";

            if (target != null)
            {
                toTarget = string.Format("$A$ {0}s {1}you.", verb, obj);

                if (blocked)
                {
                    switch (avoidanceType)
                    {
                    case ReadinessState.Circle:     //circle is dodge essentially
                        toActor  = string.Format("{0} dodges your attack!", actorTargetGlyph);
                        toTarget = string.Format("You dodge $A$'s {0}.", verb);
                        toOrigin = string.Format("$A$ {0}s {2}{1} but they dodge.", verb, targetGlyph, subject);
                        break;

                    case ReadinessState.Block:
                        toActor  = string.Format("You {0} {2}{1} but they block!", verb, actorTargetGlyph, subject);
                        toTarget = string.Format("$A$ {0}s {1}you but you block it.", verb, subject);
                        toOrigin = string.Format("$A$ {0}s {2}{1} but they block.", verb, targetGlyph, subject);
                        break;

                    case ReadinessState.Deflect:
                        toActor  = string.Format("You {0} {2}{1} but they deflect it!", verb, actorTargetGlyph, subject);
                        toTarget = string.Format("$A$ {0}s {1}you but you deflect it.", verb, subject);
                        toOrigin = string.Format("$A$ {0}s {2}{1} but they deflect the blow.", verb, targetGlyph, subject);
                        break;

                    case ReadinessState.Redirect:
                        toActor  = string.Format("{0} redirects your attack back to you!", actorTargetGlyph);
                        toTarget = string.Format("You redirect $A$s {0} back at them.", verb);
                        toOrigin = string.Format("$A$ {0}s {2}{1} but they redirect the attack back at them.", verb, targetGlyph, subject);
                        break;

                    case ReadinessState.Offensive:
                        //successful clash
                        toActor  = string.Format("{0}'s attack clashes with yours!", actorTargetGlyph);
                        toTarget = string.Format("Your attack clashes with $A$'s.", verb);
                        toOrigin = string.Format("$A$'s {0} clashes with {1}'s attack.", verb, targetGlyph);
                        break;
                    }
                }
            }

            return(new Tuple <string, string, string>(toActor, toTarget, toOrigin));
        }
Пример #4
0
        public ActionResult FightingArtEdit(int id, AddEditFightingArtViewModel vModel)
        {
            ApplicationUser authedUser = UserManager.FindById(User.Identity.GetUserId());

            IFightingArt obj = TemplateCache.Get <IFightingArt>(id);

            if (obj == null)
            {
                string message = "That does not exist";
                return(RedirectToRoute("Index", new { StatusMessage = message }));
            }

            if (vModel.DataObject.CalculateCostRatio() > 0)
            {
                ViewData.Add("Message", "The Calculated Cost must be equal to or below zero.");
                return(View("~/Views/Manage/FightingArtEdit.cshtml", vModel));
            }

            obj.Name            = vModel.DataObject.Name;
            obj.ActorCriteria   = vModel.DataObject.ActorCriteria;
            obj.Aim             = vModel.DataObject.Aim;
            obj.Armor           = vModel.DataObject.Armor;
            obj.DistanceChange  = vModel.DataObject.DistanceChange;
            obj.DistanceRange   = vModel.DataObject.DistanceRange;
            obj.Health          = vModel.DataObject.Health;
            obj.HelpText        = vModel.DataObject.HelpText;
            obj.Impact          = vModel.DataObject.Impact;
            obj.PositionResult  = vModel.DataObject.PositionResult;
            obj.Recovery        = vModel.DataObject.Recovery;
            obj.RekkaKey        = vModel.DataObject.RekkaKey;
            obj.RekkaPosition   = vModel.DataObject.RekkaPosition;
            obj.Setup           = vModel.DataObject.Setup;
            obj.Stamina         = vModel.DataObject.Stamina;
            obj.VictimCriteria  = vModel.DataObject.VictimCriteria;
            obj.ResultQuality   = vModel.DataObject.ResultQuality;
            obj.AdditiveQuality = vModel.DataObject.AdditiveQuality;
            obj.QualityValue    = vModel.DataObject.QualityValue;
            obj.Readiness       = vModel.DataObject.Readiness;
            obj.ActionVerb      = vModel.DataObject.ActionVerb;
            obj.ActionPredicate = vModel.DataObject.ActionPredicate;


            if (obj.Save(authedUser.GameAccount, authedUser.GetStaffRank(User)))
            {
                LoggingUtility.LogAdminCommandUsage("*WEB* - EditFightingArt[" + obj.Id.ToString() + "]", authedUser.GameAccount.GlobalIdentityHandle);
            }
            else
            {
            }

            return(RedirectToAction("Index"));
        }
Пример #5
0
        public ActionResult FightingArtRemove(long removeId = -1, string authorizeRemove = "", long unapproveId = -1, string authorizeUnapprove = "")
        {
            string message;

            if (!string.IsNullOrWhiteSpace(authorizeRemove) && removeId.ToString().Equals(authorizeRemove))
            {
                ApplicationUser authedUser = UserManager.FindById(User.Identity.GetUserId());

                IFightingArt obj = TemplateCache.Get <IFightingArt>(removeId);

                if (obj == null)
                {
                    message = "That does not exist";
                }
                else if (obj.Remove(authedUser.GameAccount, authedUser.GetStaffRank(User)))
                {
                    LoggingUtility.LogAdminCommandUsage("*WEB* - RemoveRoom[" + removeId.ToString() + "]", authedUser.GameAccount.GlobalIdentityHandle);
                    message = "Delete Successful.";
                }
                else
                {
                    message = "Error; Removal failed.";
                }
            }
            else if (!string.IsNullOrWhiteSpace(authorizeUnapprove) && unapproveId.ToString().Equals(authorizeUnapprove))
            {
                ApplicationUser authedUser = UserManager.FindById(User.Identity.GetUserId());

                IFightingArt obj = TemplateCache.Get <IFightingArt>(unapproveId);

                if (obj == null)
                {
                    message = "That does not exist";
                }
                else if (obj.ChangeApprovalStatus(authedUser.GameAccount, authedUser.GetStaffRank(User), ApprovalState.Returned))
                {
                    LoggingUtility.LogAdminCommandUsage("*WEB* - UnapproveRoom[" + unapproveId.ToString() + "]", authedUser.GameAccount.GlobalIdentityHandle);
                    message = "Unapproval Successful.";
                }
                else
                {
                    message = "Error; Unapproval failed.";
                }
            }
            else
            {
                message = "You must check the proper remove or unapprove authorization radio button first.";
            }

            return(RedirectToAction("Index", new { Message = message }));
        }
Пример #6
0
        public ActionResult Add(AddEditFightingArtViewModel vModel)
        {
            string          message    = string.Empty;
            ApplicationUser authedUser = UserManager.FindById(User.Identity.GetUserId());

            IFightingArt newObj = vModel.DataObject;

            if (newObj.Create(authedUser.GameAccount, authedUser.GetStaffRank(User)) == null)
            {
                message = "Error; Creation failed.";
            }
            else
            {
                LoggingUtility.LogAdminCommandUsage("*WEB* - AddFightingArt[" + newObj.Id.ToString() + "]", authedUser.GameAccount.GlobalIdentityHandle);
            }

            return(RedirectToAction("Index", new { Message = message }));
        }
Пример #7
0
        public ActionResult FightingArtEdit(int id)
        {
            string       message = string.Empty;
            IFightingArt obj     = TemplateCache.Get <IFightingArt>(id);

            if (obj == null)
            {
                message = "That does not exist";
                return(RedirectToRoute("ErrorOrClose", new { Message = message }));
            }

            AddEditFightingArtViewModel vModel = new AddEditFightingArtViewModel
            {
                AuthedUser = UserManager.FindById(User.Identity.GetUserId()),
                DataObject = obj,
            };

            return(View("~/Views/Manage/FightingArtEdit.cshtml", vModel));
        }
Пример #8
0
        public ActionResult FightingArtAdd(AddEditFightingArtViewModel vModel)
        {
            string          message    = string.Empty;
            ApplicationUser authedUser = UserManager.FindById(User.Identity.GetUserId());

            IFightingArt newObj = vModel.DataObject;

            if (newObj.CalculateCostRatio() > 0)
            {
                ViewData.Add("Message", "The Calculated Cost must be equal to or below zero.");
                return(View("~/Views/Manage/FightingArtAdd.cshtml", vModel));
            }

            if (newObj.Create(authedUser.GameAccount, authedUser.GetStaffRank(User)) == null)
            {
                message = "Error; Creation failed.";
            }
            else
            {
                LoggingUtility.LogAdminCommandUsage("*WEB* - AddFightingArt[" + newObj.Id.ToString() + "]", authedUser.GameAccount.GlobalIdentityHandle);
            }

            return(RedirectToAction("FightingArts", new { Message = message }));
        }
Пример #9
0
        /// <summary>
        /// Execute an attack round
        /// </summary>
        /// <param name="actor">the person attacking</param>
        /// <param name="target">the person defending</param>
        public static bool ExecuteRound(IMobile actor, IMobile target)
        {
            //Stagger clearance comes before ending a fight
            if (actor.Stagger > 0)
            {
                actor.Stagger -= 1;
                //Send a ui update
                actor.WriteTo(null);
                return(true);
            }

            if (!actor.IsFighting())
            {
                return(false);
            }

            if (actor == target)
            {
                target = null;
            }

            IFightingArt attack = actor.LastAttack;

            var rand = new Random();

            //If we lack an attack or we're on the tail end of the attack just find a new one and start it
            if (attack == null || !actor.Executing)
            {
                IFightingArtCombination myCombo = actor.LastCombo;
                if (myCombo == null)
                {
                    var   weights  = GetUsageWeights(actor, target);
                    ulong distance = 0;

                    if (target != null)
                    {
                        distance = 1;
                    }

                    var validCombos = actor.Combos.Where(combo => combo.IsValid(actor, target, distance));

                    if (validCombos.Count() == 0)
                    {
                        myCombo = actor.Combos.OrderByDescending(combo => weights[combo.SituationalUsage] * rand.NextDouble()).FirstOrDefault();
                    }
                    else
                    {
                        myCombo = validCombos.OrderByDescending(combo => weights[combo.SituationalUsage] * rand.NextDouble()).FirstOrDefault();
                    }
                }

                //uhh k we need to use a fake combo logic to get a random attack
                if (myCombo == null)
                {
                    var attacks = TemplateCache.GetAll <IFightingArt>(true);

                    attack = attacks.Where(atk => atk.IsValid(actor, target, (ulong)Math.Abs(actor.Balance))).OrderBy(atk => Guid.NewGuid()).FirstOrDefault();
                }
                else
                {
                    attack = myCombo.GetNext(actor.LastAttack);
                }

                if (attack == null)
                {
                    //we have no valid attacks, so we're tired
                    actor.Stagger += 10;
                    actor.Sleep(1); //recover stamina
                    actor.WriteTo(null);
                    return(true);
                }

                actor.Stagger    = attack.Setup;
                actor.Sturdy     = attack.Armor;
                actor.LastCombo  = myCombo;
                actor.LastAttack = attack;
                actor.Executing  = true;

                if (actor.Stagger > 0)
                {
                    actor.Stagger -= 1;

                    //Send a ui update
                    actor.WriteTo(null);
                    return(true);
                }
                //else we just run right into the combo if there's no setup
            }

            //execute the attack
            actor.Executing = false;

            //basics
            actor.Stagger    = attack.Recovery;
            actor.LastAttack = attack;
            actor.LastCombo  = null;
            actor.Balance    = attack.DistanceChange;

            //numbers damage
            if (attack.Health.Actor > 0)
            {
                actor.Harm(attack.Health.Actor);
            }

            if (attack.Stamina.Actor > 0)
            {
                actor.Exhaust(attack.Stamina.Actor);
            }

            Tuple <string, string, string> messaging = null;

            if (target != null)
            {
                target.Balance = -1 * attack.DistanceChange;

                var targetReadiness = ReadinessState.Offensive; //attacking is default
                var targetDirection = AnatomyAim.Mid;           //mid is default

                if (target.LastAttack != null)
                {
                    targetReadiness = target.LastAttack.Readiness;
                    targetDirection = target.LastAttack.Aim;
                }

                //TODO: for now we're just doing flat chances for avoidance states since we have no stats to base anything on
                var    avoided         = false;
                var    blocked         = false;
                double impact          = attack.Impact;
                double damage          = attack.Health.Victim;
                double staminaDrain    = attack.Stamina.Victim;
                var    aimDifferential = Math.Abs(attack.Aim - targetDirection);

                //no blocking if it's not an attack
                if (attack.Readiness != ReadinessState.Offensive || attack.Health.Victim > 0)
                {
                    switch (targetReadiness)
                    {
                    case ReadinessState.Circle:     //circle is dodge essentially
                        avoided = rand.Next(0, 100) <= Math.Max(1, Math.Abs(target.Balance)) / (Math.Max(1, aimDifferential + target.Stagger) * 4) * 100;
                        break;

                    case ReadinessState.Block:
                        blocked = rand.Next(0, 100) <= Math.Max(1, Math.Abs(target.Balance)) / (Math.Max(1, aimDifferential + target.Stagger) * 2) * 100;

                        if (blocked)
                        {
                            impact       *= .25;
                            damage       *= .50;
                            staminaDrain *= .50;
                        }
                        ;
                        break;

                    case ReadinessState.Deflect:
                        blocked = rand.Next(0, 100) <= Math.Max(1, Math.Abs(target.Balance)) / (Math.Max(1, aimDifferential + target.Stagger) * 2) * 100;

                        if (blocked)
                        {
                            impact       *= .50;
                            damage       *= .25;
                            staminaDrain *= .25;
                        }
                        break;

                    case ReadinessState.Redirect:
                        avoided = rand.Next(0, 100) <= Math.Max(1, Math.Abs(target.Balance)) / (Math.Max(1, aimDifferential + target.Stagger) * 20) * 100;
                        break;

                    case ReadinessState.Offensive:
                        //Clash mechanics, only works if the target is mid-execution
                        if (target.LastAttack != null && aimDifferential == 0 && target.Executing)
                        {
                            var impactDifference = target.LastAttack.Impact + target.LastAttack.Armor - attack.Impact;

                            if (impactDifference > 0)
                            {
                                blocked       = true;
                                impact        = 0;
                                damage       /= impactDifference;
                                staminaDrain *= .75;
                            }
                        }
                        break;
                    }
                }

                messaging = GetOutputStrings(attack, target, avoided || blocked, targetReadiness);

                if (!avoided)
                {
                    var victStagger = target.Sturdy - (int)Math.Truncate(impact);

                    //Affect the victim, sturdy/armor absorbs stagger impact and the remainder gets added to victim stagger
                    target.Sturdy   = Math.Max(0, victStagger);
                    target.Stagger += Math.Abs(Math.Min(0, victStagger));

                    if (damage > 0)
                    {
                        target.Harm((int)Math.Truncate(damage));
                    }

                    if (staminaDrain > 0)
                    {
                        target.Exhaust((int)Math.Truncate(staminaDrain));
                    }

                    //affect qualities
                    if (attack.QualityValue != 0 && !string.IsNullOrWhiteSpace(attack.ResultQuality))
                    {
                        target.SetQuality(attack.QualityValue, attack.ResultQuality, attack.AdditiveQuality);
                    }
                }
            }
            else
            {
                messaging = GetOutputStrings(attack, target, false, ReadinessState.Offensive);
            }

            var msg = new Message(new LexicalParagraph(messaging.Item1))
            {
                ToTarget = new LexicalParagraph[] { new LexicalParagraph(messaging.Item2) },
                ToOrigin = new LexicalParagraph[] { new LexicalParagraph(messaging.Item3) }
            };


            msg.ExecuteMessaging(actor, null, target, actor.CurrentLocation.CurrentContainer, null, true);

            return(true);
        }