public static string AttackLocation(Player player, BuffBox buffs) { ILocationInfoRepository repo = new EFLocationInfoRepository(); ICovenantRepository covRepo = new EFCovenantRepository(); var location = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == player.dbLocationName); var output = ""; if (location == null) { output = "You cast an enchantment here, but you aren't actually anywhere!"; return(output); } var info = repo.LocationInfos.FirstOrDefault(l => l.dbName == player.dbLocationName) ?? new LocationInfo { TakeoverAmount = 75, CovenantId = -1, dbName = player.dbLocationName, }; if (player.Covenant == null) { output = "You cast an enchantment here, but it did no effect as you aren't part of a covenant"; return(output); } if (info.TakeoverAmount >= 100 && info.CovenantId == player.Covenant) { output = "You cast an enchantment here, but it did no effect as this location's enchantment is already at its highest possible level, 100."; return(output); } var takeoverAmount = (float)player.Level / 2.0F; takeoverAmount += buffs.EnchantmentBoost; decimal XPGain = 0; try { XPGain = 40 / Math.Round(Convert.ToDecimal(101 - Math.Abs(info.TakeoverAmount)), 1); } catch (Exception) { XPGain = 0; } if (XPGain > PvPStatics.XP__EnchantmentMaxXP) { XPGain = PvPStatics.XP__EnchantmentMaxXP; } var XPGainText = String.Format("{0:0.#}", XPGain); // location is not controlled; give it to whichever covenant is attacking it if (info.TakeoverAmount <= 0) { info.CovenantId = (int)player.Covenant; info.TakeoverAmount = takeoverAmount; if (info.TakeoverAmount > 100) { info.TakeoverAmount = 100; } info.LastTakeoverTurn = PvPWorldStatProcedures.GetWorldTurnNumber(); output = "<b>Your enchantment settles in this location, converting its energies from the previous controlling covenant to your own! (+" + XPGainText + " XP)</b>"; location.CovenantController = (int)player.Covenant; location.TakeoverAmount = info.TakeoverAmount; var myCov = covRepo.Covenants.First(c => c.Id == player.Covenant); var locationLogMessage = "<b class='playerAttackNotification'>" + player.GetFullName() + " enchanted this location and claimed it for " + myCov.Name + "!</b>"; LocationLogProcedures.AddLocationLog(player.dbLocationName, locationLogMessage); var covLogWinner = player.GetFullName() + " enchanted " + location.Name + " and has claimed it for this covenant."; CovenantProcedures.WriteCovenantLog(covLogWinner, myCov.Id, true); } // otherwise the location is controlled by someone else { // add points toward the attacker's covenant or take them away if it belongs to another if (info.CovenantId == player.Covenant) { info.TakeoverAmount += takeoverAmount; location.TakeoverAmount = info.TakeoverAmount; var cov = covRepo.Covenants.FirstOrDefault(c => c.Id == player.Covenant); output = $"Your enchantment reinforces this location by {takeoverAmount}. New influence level is {info.TakeoverAmount} for your covenant, {cov?.Name ?? "unknown"}. (+{XPGainText} XP)</b>"; } else { info.TakeoverAmount -= takeoverAmount; location.TakeoverAmount = info.TakeoverAmount; var cov = info.CovenantId == null ? null : covRepo.Covenants.FirstOrDefault(c => c.Id == info.CovenantId); if (info.TakeoverAmount <= 0) { // notify old covenant who stole the location and their covenant if (info.CovenantId != null && info.CovenantId > 0) { var attackingCov = CovenantProcedures.GetCovenantViewModel((int)player.Covenant); var covLogLoser = player.GetFullName() + " of " + attackingCov.dbCovenant.Name + " enchanted " + location.Name + ", removing it from this covenant's influence!"; CovenantProcedures.WriteCovenantLog(covLogLoser, (int)info.CovenantId, true); } info.CovenantId = -1; info.LastTakeoverTurn = PvPWorldStatProcedures.GetWorldTurnNumber(); } if (cov != null) { output = "You dispel the enchantment at this location by " + takeoverAmount + ". New influence level is " + info.TakeoverAmount + " for the location's existing controller, " + cov.Name + ". (+" + XPGainText + " XP)</b>"; } else { output = "You dispel the enchantment at this location by " + takeoverAmount + ". New influence level is " + info.TakeoverAmount + ". (+" + XPGainText + " XP)</b>"; } } var locationLogMessage = "<span class='playerAttackNotification'>" + player.GetFullName() + " cast an enchantment on this location.</span>"; LocationLogProcedures.AddLocationLog(player.dbLocationName, locationLogMessage); } if (info.TakeoverAmount > 100) { info.TakeoverAmount = 100; } // cap at 0 to 100 points else if (info.TakeoverAmount <= 0) { info.CovenantId = -1; info.TakeoverAmount = 0; } repo.SaveLocationInfo(info); PlayerProcedures.GiveXP(player, XPGain); PlayerLogProcedures.AddPlayerLog(player.Id, output, false); return(output); }
public static string ReturnToAnimate(Player player, bool dungeonPenalty) { IInanimateXPRepository inanimXpRepo = new EFInanimateXPRepository(); IItemRepository itemRepo = new EFItemRepository(); var inanimXP = inanimXpRepo.InanimateXPs.FirstOrDefault(i => i.OwnerId == player.Id); var currentGameTurn = PvPWorldStatProcedures.GetWorldTurnNumber(); if (inanimXP == null) { inanimXP = new InanimateXP { OwnerId = player.Id, Amount = 0, // set the initial times struggled proportional to how high of a level the player is TimesStruggled = -6 * player.Level, LastActionTimestamp = DateTime.UtcNow, LastActionTurnstamp = currentGameTurn - 1, }; } double strugglebonus = currentGameTurn - inanimXP.LastActionTurnstamp; if (strugglebonus > TurnTimesStatics.GetItemMaxTurnsBuildup()) { strugglebonus = TurnTimesStatics.GetItemMaxTurnsBuildup(); } if (strugglebonus < 0) { strugglebonus = 0; } if (PvPStatics.ChaosMode) { strugglebonus = 100; } // increment the player's attack count. Also decrease their player XP some. IPlayerRepository playerRepo = new EFPlayerRepository(); var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == player.Id); dbPlayer.TimesAttackingThisUpdate++; var strugglesMade = Convert.ToDouble(GetStruggleChance(player, dungeonPenalty)); var rand = new Random(); var roll = rand.NextDouble() * 100; var dbPlayerItem = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer { PlayerId = player.Id }); if (dbPlayerItem == null) { return("Cannot struggle - no player item"); } if (dbPlayerItem.Owner != null) { var owner = PlayerProcedures.GetPlayer(dbPlayerItem.Owner.Id); dbPlayer.dbLocationName = owner.dbLocationName; } var itemPlus = ItemStatics.GetStaticItem(dbPlayerItem.ItemSource.Id); if (roll < strugglesMade) { // assert that the covenant the victim is in is not too full to accept them back in if (dbPlayer.Covenant > 0) { var victimCov = CovenantProcedures.GetCovenantViewModel((int)dbPlayer.Covenant).dbCovenant; if (victimCov != null && CovenantProcedures.GetPlayerCountInCovenant(victimCov, true) >= PvPStatics.Covenant_MaximumAnimatePlayerCount) { return("Although you had enough energy to break free from your body as a " + itemPlus.FriendlyName + " and restore your regular body, you were unfortunately not able to break free because there is no more room in your covenant for any more animate mages."); } } // if the item has an owner, notify them via a message. if (dbPlayerItem.Owner != null) { var message = player.FirstName + " " + player.LastName + ", your " + itemPlus.FriendlyName + ", successfully struggles against your magic and reverses their transformation. You can no longer claim them as your property, not unless you manage to turn them back again..."; PlayerLogProcedures.AddPlayerLog(dbPlayerItem.Owner.Id, message, true); } // change the player's form and mobility DomainRegistry.Repository.Execute(new ChangeForm { PlayerId = dbPlayer.Id, FormSourceId = dbPlayer.OriginalFormSourceId }); dbPlayer.ActionPoints = TurnTimesStatics.GetActionPointLimit(); dbPlayer.ActionPoints_Refill = TurnTimesStatics.GetActionPointReserveLimit(); dbPlayer.CleansesMeditatesThisRound = PvPStatics.MaxCleansesMeditatesPerUpdate; dbPlayer.TimesAttackingThisUpdate = PvPStatics.MaxAttacksPerUpdate; // don't let the player spawn in the dungeon as they will have Back On Your Feet // and may not be meet the level and game mode requirements if (dbPlayer.IsInDungeon()) { dbPlayer.dbLocationName = LocationsStatics.GetRandomLocationNotInDungeon(); } dbPlayer = PlayerProcedures.ReadjustMaxes(dbPlayer, ItemProcedures.GetPlayerBuffs(dbPlayer)); dbPlayer.Health = dbPlayer.MaxHealth / 3; dbPlayer.Mana = dbPlayer.MaxHealth / 3; playerRepo.SavePlayer(dbPlayer); // drop any runes embedded on the player-item, or return them to the former owner's inventory DomainRegistry.Repository.Execute(new UnbembedRunesOnItem { ItemId = dbPlayerItem.Id }); // delete the item or animal that this player had turned into itemRepo.DeleteItem(dbPlayerItem.Id); // delete the inanimate XP item inanimXpRepo.DeleteInanimateXP(inanimXP.Id); // give the player the recovery buff EffectProcedures.GivePerkToPlayer(PvPStatics.Effect_BackOnYourFeetSourceId, dbPlayer); var msg = "You have managed to break free from your form as " + itemPlus.FriendlyName + " and occupy an animate body once again!"; if (PvPStatics.ChaosMode) { msg += $" [CHAOS MODE: Struggle value overriden to {strugglebonus:0}% per struggle.]"; } PlayerLogProcedures.AddPlayerLog(dbPlayer.Id, msg, false); StatsProcedures.AddStat(dbPlayer.MembershipId, StatsProcedures.Stat__SuccessfulStruggles, 1); return(msg); } // failure to break free; increase time struggles else { // raise the probability of success for next time somewhat proportion to how many turns they missed inanimXP.TimesStruggled += Convert.ToInt32(strugglebonus); inanimXP.LastActionTimestamp = DateTime.UtcNow; inanimXP.LastActionTurnstamp = currentGameTurn; inanimXpRepo.SaveInanimateXP(inanimXP); playerRepo.SavePlayer(dbPlayer); if (dbPlayerItem.Owner != null) { var message = $"{player.FirstName} {player.LastName}, your {itemPlus.FriendlyName}, struggles but fails to return to an animate form. [Recovery chance next struggle: {(int)GetStruggleChance(player, dungeonPenalty)}%]"; PlayerLogProcedures.AddPlayerLog(dbPlayerItem.Owner.Id, message, true); } PlayerLogProcedures.AddPlayerLog(dbPlayer.Id, "You struggled to return to a human form.", false); return($"Unfortunately you are not able to struggle free from your form as {itemPlus.FriendlyName}. Keep trying and you might succeed later... [Recovery chance next struggle: {(int)GetStruggleChance(player, dungeonPenalty)}%]"); } }