public static (bool, decimal) RunFormChangeLogic(Player victim, int attackerId, SkillViewModel skill, decimal energyAccumulated, LogBox output) { // redundant check to make sure the victim is still in a transformable state if (victim.Mobility != PvPStatics.MobilityFull) { return(false, victim.Health); } var targetForm = FormStatics.GetForm(skill.StaticSkill.FormSourceId.Value); // check and see if the target has enough points accumulated to try the form's energy requirement if (energyAccumulated < targetForm.TFEnergyRequired) { // Less than 100% TFE - don't complete form change return(false, victim.Health); } IPlayerRepository playerRepo = new EFPlayerRepository(); var dbAttacker = playerRepo.Players.FirstOrDefault(p => p.Id == attackerId); // Collect the attacker & victim TFE related buffs decimal modifiedTFEnergyPercent = CalculateTFEBonusBuff(victim, dbAttacker); // check and see if the target's health is low enough to be eligible for the TF var updatedHealth = AddExtraHealthDamage(victim, dbAttacker, targetForm.TFEnergyRequired, energyAccumulated, modifiedTFEnergyPercent, output); var completed = PotentiallyCompleteTransformation(victim, dbAttacker, targetForm, skill.StaticSkill.Id, updatedHealth, output); // if there is a duel going on, end it if all but 1 player is defeated (not in the form they started in) if (victim.InDuel > 0) { EndDuel(victim); } return(completed, updatedHealth); }
public static (bool, LogBox) AddTFEnergyToPlayer(Player victim, Player attacker, SkillViewModel skill, decimal modifier, decimal victimHealthBefore) { var output = new LogBox { AttackerLog = " ", VictimLog = " " }; var victimMaxHealth = victim.MaxHealth; // Remember this before any form change can affect it // Move old energy to pool, add pool energy to the current attack (var energyBefore, var energyAfter) = AccumulateTFEnergy(victim, attacker, skill, modifier); var eventualForm = FormStatics.GetForm(skill.StaticSkill.FormSourceId.Value); var energyAmount = $" [{energyAfter:0.00} / {eventualForm.TFEnergyRequired:0.00} TF energy]<br />"; output.AttackerLog += energyAmount; output.VictimLog += energyAmount; // Return early if victim is already in the target form if (victim.FormSourceId == eventualForm.Id && victim.Mobility == eventualForm.MobilityType) { var noTransformMessage = $"Since {victim.GetFullName()} is already in this form, the spell has no transforming effect."; output.AttackerLog += noTransformMessage; output.VictimLog += noTransformMessage; return(false, output); } // Perform any form change logic (inc extra health damage) var formChangeLog = new LogBox(); var(complete, victimHealthAfter) = TFEnergyProcedures.RunFormChangeLogic(victim, attacker.Id, skill, energyAfter, formChangeLog); // Add the spell text to the player logs (now that we know the full damage of this hit) var percentTransformedBefore = CalculateTransformationProgress(victimHealthBefore, victimMaxHealth, energyBefore, eventualForm); var percentTransformedAfter = CalculateTransformationProgress(victimHealthAfter, victimMaxHealth, energyAfter, eventualForm); LogTransformationMessages(victim, attacker, eventualForm, percentTransformedBefore, percentTransformedAfter, output); // Append energy overflow damage and form change output from earlier output.Add(formChangeLog); // Only give XP if attacker and victim are not part of the same covenant if (attacker.Covenant == null || attacker.Covenant != victim.Covenant) { AwardXP(victim, attacker, eventualForm.MobilityType, output); } return(complete, output); }
public virtual ActionResult SelfCastSend(int itemId, int skillSourceId) { var myMembershipId = User.Identity.GetUserId(); var me = PlayerProcedures.GetPlayerFromMembership(myMembershipId); // assert player is animate if (me.Mobility != PvPStatics.MobilityFull) { TempData["Error"] = "You must be animate in order to use this."; return(RedirectToAction(MVC.PvP.Play())); } // assert that this player is not in a duel if (me.InDuel > 0) { TempData["Error"] = "You must finish your duel before you use this item."; return(RedirectToAction(MVC.PvP.Play())); } // assert that this player is not in a quest if (me.InQuest > 0) { TempData["Error"] = "You must finish your quest before you use this item."; return(RedirectToAction(MVC.PvP.Play())); } // assert player has not already used an item this turn if (me.ItemsUsedThisTurn >= PvPStatics.MaxItemUsesPerUpdate) { TempData["Error"] = "You've already used an item this turn."; TempData["SubError"] = "You will be able to use another consumable type item next turn."; return(RedirectToAction(MVC.Item.MyInventory())); } var item = ItemProcedures.GetItemViewModel(itemId); // assert player does own this if (item.dbItem.OwnerId != me.Id) { TempData["Error"] = "You don't own that item."; return(RedirectToAction(MVC.PvP.Play())); } // assert that it is equipped if (!item.dbItem.IsEquipped) { TempData["Error"] = "You cannot use an item you do not have equipped."; return(RedirectToAction(MVC.PvP.Play())); } // assert this item is a transmog if (item.dbItem.ItemSourceId != ItemStatics.AutoTransmogItemSourceId) { TempData["Error"] = "You cannot change form with that item."; return(RedirectToAction(MVC.PvP.Play())); } // assert player does own this skill var skill = SkillProcedures.GetSkillViewModel(skillSourceId, me.Id); if (skill == null) { TempData["Error"] = "You do not own this spell."; return(RedirectToAction(MVC.PvP.Play())); } // assert desired form is animate if (skill.MobilityType != PvPStatics.MobilityFull) { TempData["Error"] = "The target form must be an animate form."; return(RedirectToAction(MVC.PvP.Play())); } // assert player is not already in the form of the spell if (me.FormSourceId == skill.StaticSkill.FormSourceId) { TempData["Error"] = "You are already in the target form of that spell, so doing this would do you no good."; return(RedirectToAction(MVC.PvP.Play())); } PlayerProcedures.InstantChangeToForm(me, skill.StaticSkill.FormSourceId.Value); ItemProcedures.DeleteItem(itemId); PlayerProcedures.SetTimestampToNow(me); PlayerProcedures.AddItemUses(me.Id, 1); var form = FormStatics.GetForm(skill.StaticSkill.FormSourceId.Value); TempData["Result"] = "You use a " + item.Item.FriendlyName + ", your spell bouncing through the device for a second before getting flung back at you and hitting you square in the chest, instantly transforming you into a " + form.FriendlyName + "!"; StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__TransmogsUsed, 1); return(RedirectToAction(MVC.PvP.Play())); }
public virtual ActionResult EndQuest(bool restore) { var myMembershipId = User.Identity.GetUserId(); var me = PlayerProcedures.GetPlayerFromMembership(myMembershipId); // assert that this player is in a quest if (me.InQuest <= 0) { TempData["Error"] = "You are not in a quest."; return(RedirectToAction(MVC.PvP.Play())); } var quest = QuestProcedures.GetQuest(me.InQuest); var state = QuestProcedures.GetQuestState(me.InQuestState); // assert that there is an end state to this quest state if (!state.QuestEnds.Any()) { TempData["Error"] = "You are not yet at the end of your quest!"; TempData["SubError"] = "If it is impossible for you to continue with this quest, you may abandon it."; return(RedirectToAction(MVC.Quest.Quest())); } var endType = state.QuestEnds.First().EndType; // if the player is not animate, either restore them or create a new item for them to exist as if (me.Mobility != PvPStatics.MobilityFull) { if (restore && me.Mobility != PvPStatics.MobilityFull) { PlayerProcedures.InstantRestoreToBase(me); } else if (!restore) { var newform = FormStatics.GetForm(me.FormSourceId); ItemProcedures.PlayerBecomesItem(me, newform, null); } } // fail! if (endType == (int)QuestStatics.QuestOutcomes.Failed) { QuestProcedures.PlayerEndQuest(me, (int)QuestStatics.QuestOutcomes.Failed); QuestProcedures.ClearQuestPlayerVariables(me.Id, me.InQuest); StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__QuestsFailed, 1); TempData["Result"] = "You unfortunately failed the quest <b>" + quest.Name + "</b>. Better luck next time! If there is one..."; return(RedirectToAction(MVC.PvP.Play())); } // pass! var victoryMessage = QuestProcedures.PlayerEndQuest(me, (int)QuestStatics.QuestOutcomes.Completed); QuestProcedures.ClearQuestPlayerVariables(me.Id, me.InQuest); StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__QuestsPassed, 1); TempData["Result"] = "Congratulations, you completed the quest <b>" + quest.Name + "</b>!" + victoryMessage; return(RedirectToAction(MVC.PvP.Play())); }
public static string CurseTransformOwner(Player player, Player owner, ItemDetail playerItem, bool isWhitelist) { var rand = new Random(); var roll = rand.NextDouble() * 100; IInanimateXPRepository inanimateXpRepo = new EFInanimateXPRepository(); var xp = inanimateXpRepo.InanimateXPs.FirstOrDefault(x => x.OwnerId == player.Id); var gameTurn = PvPWorldStatProcedures.GetWorldTurnNumber(); // assign the player inanimate XP based on turn building if (xp == null) { xp = new InanimateXP { OwnerId = player.Id, Amount = 0, TimesStruggled = -6 * player.Level, LastActionTimestamp = DateTime.UtcNow, LastActionTurnstamp = gameTurn - 1, }; } double chanceOfSuccess = (gameTurn - xp.LastActionTurnstamp); ITFMessageRepository tfMessageRepo = new EFTFMessageRepository(); var tf = tfMessageRepo.TFMessages.FirstOrDefault(t => t.FormSourceId == playerItem.ItemSource.CurseTFFormSourceId); var ownerSuccessMessage = ""; var ownerFailureMessage = ""; var playerMessage = ""; var newFormSourceId = -1; if (playerItem.ItemSource.CurseTFFormSourceId == null) { // No item-provided TF curse - reduce chance of transforming to a preset form chanceOfSuccess /= 4.0; newFormSourceId = PvPStatics.DefaultTFCurseForms[rand.Next(PvPStatics.DefaultTFCurseForms.Length)]; } else { // Regular TF curse - load its details newFormSourceId = playerItem.ItemSource.CurseTFFormSourceId.Value; if (playerItem.Owner.Gender == PvPStatics.GenderMale && !tf.CursedTF_Succeed_M.IsNullOrEmpty()) { ownerSuccessMessage = tf.CursedTF_Succeed_M; } else if (playerItem.Owner.Gender == PvPStatics.GenderFemale && !tf.CursedTF_Succeed_F.IsNullOrEmpty()) { ownerSuccessMessage = tf.CursedTF_Succeed_F; } else if (!tf.CursedTF_Succeed.IsNullOrEmpty()) { ownerSuccessMessage = tf.CursedTF_Succeed; } if (playerItem.Owner.Gender == PvPStatics.GenderMale && !tf.CursedTF_Fail_M.IsNullOrEmpty()) { ownerFailureMessage = tf.CursedTF_Fail_M; } else if (playerItem.Owner.Gender == PvPStatics.GenderFemale && !tf.CursedTF_Fail_F.IsNullOrEmpty()) { ownerFailureMessage = tf.CursedTF_Fail_F; } else if (!tf.CursedTF_Fail.IsNullOrEmpty()) { ownerFailureMessage = tf.CursedTF_Fail; } } // success; owner is transformed! if (roll < chanceOfSuccess) { IPlayerRepository playerRepo = new EFPlayerRepository(); var newForm = FormStatics.GetForm(newFormSourceId); if (newForm.MobilityType == PvPStatics.MobilityFull) { DomainRegistry.Repository.Execute(new ChangeForm { PlayerId = playerItem.Owner.Id, FormSourceId = newFormSourceId }); var dbOwner = playerRepo.Players.FirstOrDefault(p => p.Id == playerItem.Owner.Id); dbOwner.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(dbOwner)); dbOwner.Mana -= dbOwner.MaxMana * .5M; dbOwner.NormalizeHealthMana(); playerRepo.SavePlayer(dbOwner); if (ownerSuccessMessage.IsNullOrEmpty()) { ownerSuccessMessage = $"One of your items, {playerItem.FormerPlayer.FullName}, attempts to trigger a curse placed upon it. Suddenly you are overwhelmed as you find yourself transformed into a {newForm.FriendlyName}!"; } playerMessage = "Your subtle transformation curse overwhelms your owner, transforming them into a " + newForm.FriendlyName + "!"; PlayerLogProcedures.AddPlayerLog(playerItem.Owner.Id, ownerSuccessMessage, true); LocationLogProcedures.AddLocationLog(owner.dbLocationName, "<b> " + owner.GetFullName() + " is suddenly transformed by " + playerItem.FormerPlayer.FullName + " the " + playerItem.ItemSource.FriendlyName + ", one of their belongings!</b>"); } } // fail; owner is not transformed else { if (ownerFailureMessage.IsNullOrEmpty()) { ownerFailureMessage = "One of your items attempts to trigger a curse placed upon it, but it fails to transform you."; } playerMessage = "Unfortunately your subtle transformation curse fails to transform your owner."; PlayerLogProcedures.AddPlayerLog(owner.Id, ownerFailureMessage, true); } PlayerProcedures.AddAttackCount(player); return(playerMessage + GiveInanimateXP(player.MembershipId, isWhitelist)); }