private static void EngageMindControl(Player target, Player attacker, DbStaticForm targetForm, LogBox output) { //Player attacker = playerRepo.Players.FirstOrDefault(p => p.Id == attackerId); MindControlProcedures.AddMindControl(attacker, target, targetForm.Id); output.LocationLog += $"<br><b>{target.GetFullName()} was partially mind controlled by {attacker.GetFullName()} here.</b>"; output.AttackerLog += $"<br><b>You have seized the mind of {target.GetFullName()}! You can now force them into performing certain actions.</b>"; output.VictimLog += $"<br><b>You are now being partially mind controlled by {targetForm.FriendlyName}!</b>"; TFEnergyProcedures.DeleteAllPlayerTFEnergiesOfFormSourceId(target.Id, targetForm.Id); // Remove any Self Restore entires. RemoveSelfRestore(target); // give curse debuff if (targetForm.Id == MindControlStatics.MindControl__MovementFormSourceId) { EffectProcedures.GivePerkToPlayer(MindControlStatics.MindControl__Movement_DebuffEffectSourceId, target); } else if (targetForm.Id == MindControlStatics.MindControl__StripFormSourceId) { EffectProcedures.GivePerkToPlayer(MindControlStatics.MindControl__Strip_DebuffEffectSourceId, target); } else if (targetForm.Id == MindControlStatics.MindControl__MeditateFormSourceId) { EffectProcedures.GivePerkToPlayer(MindControlStatics.MindControl__Strip_DebuffEffectSourceId, target); } }
public void SaveDbStaticForm(DbStaticForm DbStaticForm) { if (DbStaticForm.Id == 0) { context.DbStaticForms.Add(DbStaticForm); } else { var editMe = context.DbStaticForms.Find(DbStaticForm.Id); if (editMe != null) { // dbEntry.Name = DbStaticForm.Name; // dbEntry.Message = DbStaticForm.Message; // dbEntry.TimeStamp = DbStaticForm.TimeStamp; } } context.SaveChanges(); }
public void LoadBalanceBox(DbStaticForm input) { BuffStats = new List <BuffStat>(); var addme = new BuffStat(); if (input.Discipline != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Discipline), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Perception != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Perception), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Charisma != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Charisma), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Fortitude != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Fortitude), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Agility != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Agility), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Allure != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Allure), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Magicka != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Magicka), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Succour != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Succour), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } if (input.Luck != 0) { addme = new BuffStat { Amount = Convert.ToDecimal(input.Luck), Value = 1, NegativeModifier = 0, NegativeCap = -99999, }; this.BuffStats.Add(addme); } }
public static void ClaimReward(Player attacker, Player victim, DbStaticForm victimNewForm) { if (attacker == null || victim == null || victimNewForm == null) { return; } // Ensure victim is still in PvP, or not a player (in case we want to support bounties on NPCs) if (victim.BotId == AIStatics.ActivePlayerBotId && victim.GameMode != (int)GameModeStatics.GameModes.PvP) { return; } // NPCs are not eligible to claim bounties if (attacker.BotId != AIStatics.ActivePlayerBotId) { return; } // Only reward PvP players to avoid friend list/alt abuse if (attacker.GameMode != (int)GameModeStatics.GameModes.PvP) { return; } var bountyStaticEffectIds = MAPPINGS.Select(se => se.EffectSourceId); var victimEffects = EffectProcedures.GetPlayerEffects2(victim.Id).Where(e => bountyStaticEffectIds.Contains(e.dbEffect.EffectSourceId)); var award = 0; foreach (var victimEffect in victimEffects) { var bounty = BountyDetails(victim, victimEffect.dbEffect.EffectSourceId); if (bounty == null) { continue; } if (victimNewForm.Id == bounty.Form?.Id) { // Victim has been turned into the requested form - full reward award = bounty.CurrentReward; } else if (victimNewForm.ItemSourceId.HasValue) { // Award half bounty for a different inanimate form of the same type IDbStaticItemRepository itemsRepo = new EFDbStaticItemRepository(); var itemForm = itemsRepo.DbStaticItems.FirstOrDefault(i => i.Id == victimNewForm.ItemSourceId.Value); if (itemForm?.ItemType == bounty.Category) { award = bounty.CurrentReward / 2; } } if (award > 0) { // Release the victim from the claimed bounty EffectProcedures.SetPerkDurationToZero(victimEffect.dbEffect.EffectSourceId, victim); // Award bounty funds to attacker PlayerLogProcedures.AddPlayerLog(attacker.Id, $"For turning {victim.GetFullName()} into a {victimNewForm.FriendlyName} you claim a bounty of {award} arpeyjis.", true); PlayerProcedures.GiveMoneyToPlayer(attacker, award); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__BountiesClaimed, award); break; } } }
private static string GetTFMessage(DbStaticForm form, Player victim, Player attacker, string PoV, int previousStage, int finalStage) { var output = ""; ITFMessageRepository tfMessageRepo = new EFTFMessageRepository(); var tfMessage = tfMessageRepo.TFMessages.FirstOrDefault(t => t.FormSourceId == form.Id); if (tfMessage == null) { return("ERROR RETRIEVING TRANSFORMATION TEXT. This is a bug."); } var attackerName = attacker.GetFullName(); var victimName = victim.GetFullName(); // 0-20 percent TF var currentStage = 0; if (finalStage == currentStage || (finalStage > currentStage && previousStage < currentStage)) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, currentStage, tfMessage.TFMessage_20_Percent_1st, tfMessage.TFMessage_20_Percent_1st_M, tfMessage.TFMessage_20_Percent_1st_F, tfMessage.TFMessage_20_Percent_3rd, tfMessage.TFMessage_20_Percent_3rd_M, tfMessage.TFMessage_20_Percent_3rd_F); } // 20-40 percent TF currentStage = 1; if (finalStage == currentStage || (finalStage > currentStage && previousStage < currentStage)) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, currentStage, tfMessage.TFMessage_40_Percent_1st, tfMessage.TFMessage_40_Percent_1st_M, tfMessage.TFMessage_40_Percent_1st_F, tfMessage.TFMessage_40_Percent_3rd, tfMessage.TFMessage_40_Percent_3rd_M, tfMessage.TFMessage_40_Percent_3rd_F); } // 40-60 percent TF currentStage = 2; if (finalStage == currentStage || (finalStage > currentStage && previousStage < currentStage)) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, 2, tfMessage.TFMessage_60_Percent_1st, tfMessage.TFMessage_60_Percent_1st_M, tfMessage.TFMessage_60_Percent_1st_F, tfMessage.TFMessage_60_Percent_3rd, tfMessage.TFMessage_60_Percent_3rd_M, tfMessage.TFMessage_60_Percent_3rd_F); } // 60-80 percent TF currentStage = 3; if (finalStage == currentStage || (finalStage > currentStage && previousStage < currentStage)) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, 3, tfMessage.TFMessage_80_Percent_1st, tfMessage.TFMessage_80_Percent_1st_M, tfMessage.TFMessage_80_Percent_1st_F, tfMessage.TFMessage_80_Percent_3rd, tfMessage.TFMessage_80_Percent_3rd_M, tfMessage.TFMessage_80_Percent_3rd_F); } // 80-100 percent TF currentStage = 4; if (finalStage == currentStage || (finalStage > currentStage && previousStage < currentStage)) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, currentStage, tfMessage.TFMessage_100_Percent_1st, tfMessage.TFMessage_100_Percent_1st_M, tfMessage.TFMessage_100_Percent_1st_F, tfMessage.TFMessage_100_Percent_3rd, tfMessage.TFMessage_100_Percent_3rd_M, tfMessage.TFMessage_100_Percent_3rd_F); } // complete TF currentStage = 5; if (finalStage >= currentStage) { output += AddStageMessage(victim, attacker, PoV, previousStage, finalStage, currentStage, tfMessage.TFMessage_Completed_1st, tfMessage.TFMessage_Completed_1st_M, tfMessage.TFMessage_Completed_1st_F, tfMessage.TFMessage_Completed_3rd, tfMessage.TFMessage_Completed_3rd_M, tfMessage.TFMessage_Completed_3rd_F); } return(output); }
private static void PerformInanimateTransformation(Player victim, Player attacker, int skillSourceId, DbStaticForm targetForm, LogBox output) { SkillProcedures.UpdateFormSpecificSkillsToPlayer(victim, targetForm.Id); DomainRegistry.Repository.Execute(new ChangeForm { PlayerId = victim.Id, FormSourceId = targetForm.Id }); if (targetForm.MobilityType == PvPStatics.MobilityInanimate && victim.BotId != AIStatics.MinibossPlushAngelId) //No reward for monsters that hurt an innocent little plush friend. :( { StatsProcedures.AddStat(victim.MembershipId, StatsProcedures.Stat__TimesInanimateTFed, 1); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__TimesInanimateTFing, 1); } else if (targetForm.MobilityType == PvPStatics.MobilityPet && victim.BotId != AIStatics.MinibossPlushAngelId) //No reward for monsters that hurt an innocent little plush friend. :( { StatsProcedures.AddStat(victim.MembershipId, StatsProcedures.Stat__TimesAnimalTFed, 1); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__TimesAnimalTFing, 1); } if (targetForm.MobilityType == PvPStatics.MobilityPet || targetForm.MobilityType == PvPStatics.MobilityInanimate) { if (victim.BotId == AIStatics.PsychopathBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__PsychopathsDefeated, 1); } if (victim.BotId == AIStatics.ActivePlayerBotId && attacker.GameMode == (int)GameModeStatics.GameModes.PvP && victim.GameMode == (int)GameModeStatics.GameModes.PvP) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__PvPPlayerNumberTakedowns, 1); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__PvPPlayerLevelTakedowns, victim.Level); } } // extra log stuff for turning into item var extra = ItemProcedures.PlayerBecomesItem(victim, targetForm, attacker); output.AttackerLog += extra.AttackerLog; output.VictimLog += extra.VictimLog; output.LocationLog += extra.LocationLog; // give some of the victim's money to the attacker, the amount depending on what mode the victim is in var moneygain = victim.Money * .35M; PlayerProcedures.GiveMoneyToPlayer(attacker, moneygain); PlayerProcedures.GiveMoneyToPlayer(victim, -moneygain / 2); var levelDifference = attacker.Level - victim.Level; // only give the lump sum XP if the victim is not in the same covenant if (attacker.Covenant == null || attacker.Covenant != victim.Covenant) { var xpGain = 100 - (PvPStatics.XP__EndgameTFCompletionLevelBase * levelDifference); if (xpGain < 50) { xpGain = 50; } else if (xpGain > 200) { xpGain = 200; } // give the attacker a nice lump sum for having completed the transformation output.AttackerLog += $" <br>For having sealed your opponent into their new form, you gain an extra <b>{xpGain}</b> XP."; output.AttackerLog += PlayerProcedures.GiveXP(attacker, xpGain); } // exclude PvP score for bots if (victim.BotId == AIStatics.ActivePlayerBotId) { var score = PlayerProcedures.GetPvPScoreFromWin(attacker, victim); if (score > 0) { output.AttackerLog += PlayerProcedures.GivePlayerPvPScore(attacker, victim, score); output.VictimLog += PlayerProcedures.RemovePlayerPvPScore(victim, attacker, score); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__DungeonPointsStolen, (float)score); } else { output.AttackerLog += $" {victim.GetFullName()} unfortunately did not have any dungeon points for you to steal for yourself."; } } // Call out a player for being the monster they are when they defeat the plush angel. if (victim.BotId == AIStatics.MinibossPlushAngelId) { output.AttackerLog += "<br><br>Why did you do that to the poor plush? They just wanted to be a friend!<br>"; output.LocationLog += $"<br><b>{attacker.GetFullName()}</b> went and bullied <b>{victim.GetFullName()}</b>, like some <b>monster</b>. The angelic plush left some flowers to the 'victor', in hope they would forgive it despite doing no wrong."; // Give the dummy a bit of madness for being a bully. EffectProcedures.GivePerkToPlayer(198, attacker); } // Heals the victorious player provided that the target was eligible if (attacker.BotId == AIStatics.ActivePlayerBotId) { // Provide no healing if the victim shared a coven with the attacker if (attacker.Covenant != null && attacker.Covenant == victim.Covenant) { output.AttackerLog += " <br>There is no glory to be had in this victory, your willpower & mana are not restored."; } else { // Figure out the modifier to be used double modifier = (levelDifference * 5) / 100; // Cap the modifier to prevent too much / too little healing. if (modifier > 0.3) { modifier = 0.3; } if (modifier < -0.55) { modifier = -0.55; } decimal healingPercent = (decimal)(0.6 + modifier); if (victim.BotId != AIStatics.ActivePlayerBotId) { // The victim is not a player, provide half of the healing. healingPercent /= 2; } // Heal the attacker and restore their Mana var healingTotal = attacker.MaxHealth * healingPercent; var manaRestoredTotal = attacker.MaxMana * healingPercent; PlayerProcedures.ChangePlayerActionMana(0, healingTotal, manaRestoredTotal, attacker.Id, false); // Remove any Self Restore entires. RemoveSelfRestore(victim); output.AttackerLog += $"<br />Invigorated by your victory and fuelled by the scattered essence that was once your foe, you are healed for {healingTotal:#} willpower and {manaRestoredTotal:#} mana."; } } output.AttackerLog += $" You collect {Math.Round(moneygain, 0)} Arpeyjis your victim dropped during the transformation."; // create inanimate XP for the victim InanimateXPProcedures.GetStruggleChance(victim, false); // if this victim is a bot, clear out some old stuff that is not needed anymore if (victim.BotId < AIStatics.ActivePlayerBotId) { AIDirectiveProcedures.DeleteAIDirectiveByPlayerId(victim.Id); PlayerLogProcedures.ClearPlayerLog(victim.Id); } TFEnergyProcedures.DeleteAllPlayerTFEnergiesOfFormSourceId(victim.Id, targetForm.Id); // if the attacker is a psycho, have them change to a new spell and equip whatever they just earned if (attacker.BotId == AIStatics.PsychopathBotId) { SkillProcedures.DeletePlayerSkill(attacker, skillSourceId); if (targetForm.MobilityType == PvPStatics.MobilityInanimate || targetForm.MobilityType == PvPStatics.MobilityPet) { if (attacker.MembershipId.IsNullOrEmpty()) { // give this bot a random replacement inanimate/pet skill var eligibleSkills = SkillStatics.GetLearnablePsychopathSkills().ToList(); var rand = new Random(); var skillToLearn = eligibleSkills.ElementAt(rand.Next(eligibleSkills.Count)); SkillProcedures.GiveSkillToPlayer(attacker.Id, skillToLearn.Id); } else { // Bot is being controlled by a player - re-add the original skill so only the ordering of skills changes SkillProcedures.GiveSkillToPlayer(attacker.Id, skillSourceId); } } } }
private static void PerformAnimateTransformation(Player victim, Player attacker, DbStaticForm targetForm, LogBox output) { var playerRepo = new EFPlayerRepository(); var dbVictim = playerRepo.Players.FirstOrDefault(p => p.Id == victim.Id); SkillProcedures.UpdateFormSpecificSkillsToPlayer(dbVictim, targetForm.Id); DomainRegistry.Repository.Execute(new ChangeForm { PlayerId = dbVictim.Id, FormSourceId = targetForm.Id }); // wipe out half of the target's mana dbVictim.Mana -= dbVictim.MaxMana / 2; if (dbVictim.Mana < 0) { dbVictim.Mana = 0; } // Remove any Self Restore entires. RemoveSelfRestore(dbVictim); var targetbuffs = ItemProcedures.GetPlayerBuffs(dbVictim); dbVictim = PlayerProcedures.ReadjustMaxes(dbVictim, targetbuffs); // take away some of the victim's XP based on the their level // target.XP += -2.5M * target.Level; playerRepo.SavePlayer(dbVictim); output.LocationLog += $"<br><b>{dbVictim.GetFullName()} was completely transformed into a {targetForm.FriendlyName} here.</b>"; output.AttackerLog += $"<br><b>You fully transformed {dbVictim.GetFullName()} into a {targetForm.FriendlyName}</b>!"; output.VictimLog += $"<br><b>You have been fully transformed into a {targetForm.FriendlyName}!</b>"; // Let the target know they are best friends with the angel plush. if (attacker.BotId == AIStatics.MinibossPlushAngelId) { output.VictimLog += $"<br><br><b>{attacker.GetFullName()}</b> was happy to make you into a new friend!<br>"; } TFEnergyProcedures.DeleteAllPlayerTFEnergiesOfFormSourceId(dbVictim.Id, targetForm.Id); StatsProcedures.AddStat(dbVictim.MembershipId, StatsProcedures.Stat__TimesAnimateTFed, 1); StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__TimesAnimateTFing, 1); }
private static bool PotentiallyCompleteTransformation(Player victim, Player attacker, DbStaticForm targetForm, int skillSourceId, decimal victimHealth, LogBox output) { var completed = false; var healthProportion = victimHealth / victim.MaxHealth; // target is turning into an animate form if (targetForm.MobilityType == PvPStatics.MobilityFull && healthProportion <= PvPStatics.PercentHealthToAllowFullMobilityFormTF) { PerformAnimateTransformation(victim, attacker, targetForm, output); completed = true; BountyProcedures.ClaimReward(attacker, victim, targetForm); } // target is turning into an inanimate or animal form, both are endgame else if ((targetForm.MobilityType == PvPStatics.MobilityInanimate && healthProportion <= PvPStatics.PercentHealthToAllowInanimateFormTF) || (targetForm.MobilityType == PvPStatics.MobilityPet && healthProportion <= PvPStatics.PercentHealthToAllowAnimalFormTF)) { PerformInanimateTransformation(victim, attacker, skillSourceId, targetForm, output); completed = true; BountyProcedures.ClaimReward(attacker, victim, targetForm); } // mind control else if (targetForm.MobilityType == PvPStatics.MobilityMindControl && healthProportion <= PvPStatics.PercentHealthToAllowMindControlTF) { EngageMindControl(victim, attacker, targetForm, output); completed = true; } return(completed); }
private static void LogTransformationMessages(Player victim, Player attacker, DbStaticForm eventualForm, decimal percentTransformedBefore, decimal percentTransformedAfter, LogBox output) { // Stage 0 = 0 - 20%, 1 = 20 - 40%, 2 = 40 - 60%, 3 = 60 - 80%, 4 = 80 - 100%, 5 = 100% complete, -1 = 0% (no TFE) var previousStage = (int)(percentTransformedBefore < 1.0M ? percentTransformedBefore / 0.2M : 5); var currentStage = (int)(percentTransformedAfter < 1.0M ? percentTransformedAfter / 0.2M : 5); if (percentTransformedBefore == 0) { // Ensure currentStage != previousStage for first hit previousStage = -1; } var percentPrintedOutput = $" ({percentTransformedAfter:0.00%})"; output.AttackerLog += GetTFMessage(eventualForm, victim, attacker, "third", previousStage, currentStage) + percentPrintedOutput; output.VictimLog += GetTFMessage(eventualForm, victim, attacker, "first", previousStage, currentStage) + percentPrintedOutput; }
private static decimal CalculateTransformationProgress(decimal victimHealth, decimal victimMaxHealth, decimal totalEnergy, DbStaticForm eventualForm) { var percentTransformedByHealth = 1 - (victimHealth / victimMaxHealth); // animate forms only need half of health requirement, so double the amount completed decimal PercentHealthToAllowTF = 0; var mobility = eventualForm.MobilityType; if (mobility == PvPStatics.MobilityFull) { PercentHealthToAllowTF = PvPStatics.PercentHealthToAllowFullMobilityFormTF; } else if (mobility == PvPStatics.MobilityInanimate) { PercentHealthToAllowTF = PvPStatics.PercentHealthToAllowInanimateFormTF; } else if (mobility == PvPStatics.MobilityPet) { PercentHealthToAllowTF = PvPStatics.PercentHealthToAllowAnimalFormTF; } else if (mobility == PvPStatics.MobilityMindControl) { PercentHealthToAllowTF = PvPStatics.PercentHealthToAllowMindControlTF; } percentTransformedByHealth /= 1 - PercentHealthToAllowTF; var percentTransformedByEnergy = Math.Min(1, totalEnergy / eventualForm.TFEnergyRequired); // only return the lower of the two tf % values return(Math.Min(percentTransformedByEnergy, percentTransformedByHealth)); }