/// <summary> /// Completes skill, healing the target. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Complete(Creature creature, Skill skill, Packet packet) { var entityId = packet.GetLong(); var unkInt1 = packet.GetInt(); var unkInt2 = packet.GetInt(); // Get target var target = ChannelServer.Instance.World.GetCreature(entityId); if (target == null) { Send.Notice(creature, Localization.Get("Invalid target.")); goto L_End; } // Check range if (!creature.GetPosition().InRange(target.GetPosition(), Range)) { Send.Notice(creature, Localization.Get("Out of range.")); goto L_End; } // Check bandage, make sure he still has the item and that // it wasn't switched with something else somehow. if (creature.Temp.SkillItem1 == null || !creature.Temp.SkillItem1.HasTag("/bandage/") || !creature.Inventory.Has(creature.Temp.SkillItem1)) { Log.Warning("FirstAid.Complete: Creature '{0:X16}' apparently switched the skill item somehow, between Ready and Complete.", creature.EntityId); Send.Notice(creature, Localization.Get("Invalid bandage.")); goto L_End; } // Remove bandage if (!creature.Inventory.Decrement(creature.Temp.SkillItem1)) { Log.Error("FirstAid.Complete: Decrementing the skill item failed somehow."); Send.Notice(creature, Localization.Get("Unknown error.")); goto L_End; } // Fails if target is moving. if (target.IsMoving) { // Unofficial Send.Notice(creature, Localization.Get("Failed because target was moving.")); // Fail motion? goto L_End; } // Heal injuries var rnd = RandomProvider.Get(); var heal = rnd.Next((int)skill.RankData.Var1, (int)skill.RankData.Var2 + 1); // Add bonus from higher grade bandages if (creature.Temp.SkillItem1.HasTag("/common_grade/")) { heal += 3; } else if (creature.Temp.SkillItem1.HasTag("/high_grade/")) { heal += 6; } else if (creature.Temp.SkillItem1.HasTag("/highest_grade/")) { heal += 10; } // 50% efficiency if target isn't resting if (!target.Has(CreatureStates.SitDown)) { heal /= 2; } target.Injuries -= heal; Send.StatUpdateDefault(target); // Skill training if (skill.Info.Rank == SkillRank.Novice) { skill.Train(1); // Use First Aid. } // First Aid animation Send.Effect(creature, Effect.UseMagic, "healing_firstaid", entityId); L_End: Send.SkillComplete(creature, skill.Info.Id, entityId, unkInt1, unkInt2); }
protected override async Task Talk() { SetBgm("NPC_Tin.mp3"); await Intro( "A little boy with a heavy helmet is looking in my direction.", "The helmet is very well polished and features a dragon on the top, but prevents me from being able to see his face.", "He speaks in a low voice, and every once in a while places his left hand on his chin to keep his helmet on,", "as it slips off little by little." ); if (!Player.Has(CreatureStates.JustRebirthed)) { Msg("Hey, who are you?"); Msg("You don't look like you're from this world. Am I right?<br/>Did you make your way down here from Soul Stream?<br/>Ahhh, so Nao sent you here!"); Msg("She's way too obedient to the Goddess' wishes.<br/>Anyway, she's a good girl, so be nice to her."); Msg("Was there something else you wanted to talk about?"); await StartConversation(); Close(Hide.None, "Go all the way to the right and you will find Tir Chonaill. <br/>I wish you the best of luck.<br/>Have a great journey. <br/>I'll see you around..."); } else { Msg("Hey, <username/>. Were you reborn?<br/>Do you remember me?"); Msg("Well... your appearance changed a little bit, but you still seem the same to me."); Msg("Was there something else you wanted to talk about?"); await StartConversation(); // Check CreatureStates.FreeRebirth? if (!HasKeyword("tutorial_present") && !IsEnabled("NoRebirthPresent")) { Msg("Hmmm... How about I give you a present since you've been reborn and all.<br/>This is a Dye you can use to dye your clothes, but unlike regular Dye, the color is already set.<br/>I'll show you ten different colors in order, so choose the one that you'd like to keep.<br/>If you don't pick one while I'm showing it to you, I won't be able to give it to you, so be sure to pick one."); // Select color var rnd = RandomProvider.Get(); var itemId = 63030; // Fixed Color Dye Ampoule uint color = 0x000000; int start = 1, max = 10; var options = "<button title='Yea, I like it.' keyword='@yes'/><button title='Show me another one.' keyword='@no'/>"; for (int i = start; i <= max; ++i) { // There are 9 keywords to save the "progress" you make // on the dyes, so you can't disconnect to get another 9 // chances. Once max is reached, you simply get whatever // color is selected, without any chances to cheat. if (i < max) { if (HasKeyword("Tin_ColorAmpul_" + i)) { continue; } GiveKeyword("Tin_ColorAmpul_" + i); } // Completely random color // Officials probably used a predefined list of colors. // This call generates completely random colors, incl. // all kinds of flashies. color = (uint)rnd.Next(int.MinValue, int.MaxValue); var image = string.Format("<image item='{0}' col1='{1:X8}'/><br/>", itemId, color); var result = "@no"; if (i == 1) { Msg(image + "Okay, let's see...<br/>How do you like this color? Do you like it?" + options); result = await Select(); } else if (i < max) { Msg(image + "Well then, what about this color?<br/>This one seems nice..." + options); result = await Select(); } else { Msg(image + "This is the last one.<br/>Since this is the last one, you'll just have to take it."); result = "@yes"; } if (result == "@yes") { break; } } // Give dye Player.AcquireItem(Item.Create(itemId, color1: color)); GiveKeyword("tutorial_present"); Msg("I'll give you a useful book here.<br/>You know how Nao keeps giving you all sorts of rare accessories?<br/>Well, try collecting all those things in this book."); } Close(Hide.None, "I wish you the best of luck.<br/>Have a great journey.<br/>I'll see you around."); } }
/// <summary> /// Class constructor /// </summary> public Provably() { mRandom = new RandomProvider(); }
/// <summary> /// Applies random fountain effect to creature. /// </summary> /// <param name="creature"></param> protected virtual void Touch(Creature creature) { var rnd = RandomProvider.Get(); // All notices are unofficial switch (rnd.Next(15)) { case 0: // Full Life { creature.FullLifeHeal(); Send.Notice(creature, Localization.Get("Full Life")); break; } case 1: // 0 Injuries { creature.Injuries = 0; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("No Injuries")); break; } case 2: // Full Stamina { creature.Stamina = creature.StaminaMax; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("Full Stamina")); break; } case 3: // Full Mana { creature.Mana = creature.ManaMax; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("Full Mana")); break; } case 4: // No Hunger { creature.Hunger = 0; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("No Hunger")); break; } case 5: // Gold { creature.GiveItem(Item.CreateGold(rnd.Next(100, 200 + 1))); Send.Notice(creature, Localization.Get("Gold")); break; } case 6: // Exp { creature.GiveExp(1000); Send.Notice(creature, Localization.Get("Exp")); break; } case 7: // Bless All { foreach (var item in creature.Inventory.ActualEquipment) { item.OptionInfo.Flags |= ItemFlags.Blessed; Send.ItemBlessed(creature, item); } Send.Notice(creature, Localization.Get("Blessed All")); break; } case 8: // Bless One { var equip = creature.Inventory.ActualEquipment.Where(a => !a.IsBlessed); var count = equip.Count(); if (count == 0) { break; } var item = equip.ElementAt(rnd.Next(count)); item.OptionInfo.Flags |= ItemFlags.Blessed; Send.ItemBlessed(creature, item); Send.Notice(creature, Localization.Get("Blessed {0}"), item.Data.Name); break; } case 9: // Repair One { var equip = creature.Inventory.ActualEquipment.Where(a => a.OptionInfo.Durability != a.OptionInfo.DurabilityMax); var count = equip.Count(); if (count == 0) { break; } var item = equip.ElementAt(rnd.Next(count)); item.OptionInfo.Durability = item.OptionInfo.DurabilityMax; Send.ItemDurabilityUpdate(creature, item); Send.Notice(creature, Localization.Get("Repaired {0}"), item.Data.Name); break; } case 10: // No Stamina and Hungry { creature.Stamina = 0; creature.Hunger = creature.StaminaMax; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("No Stamina and Hungry")); break; } case 11: // Lose one blessing { var equip = creature.Inventory.ActualEquipment.Where(a => a.IsBlessed); var count = equip.Count(); if (count == 0) { break; } var item = equip.ElementAt(rnd.Next(count)); item.OptionInfo.Flags &= ~ItemFlags.Blessed; Send.ItemBlessed(creature, item); Send.Notice(creature, Localization.Get("Lost blessing on {0}"), item.Data.Name); break; } case 12: // No Stamina { creature.Stamina = 0; Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("No Stamina")); break; } case 13: // Random Injuries { creature.Injuries = rnd.Next((int)(creature.Life * 0.9f) + 1); Send.StatUpdateDefault(creature); Send.Notice(creature, Localization.Get("Random Injuries")); break; } case 14: // Lose one durability on random equip { var equip = creature.Inventory.ActualEquipment.Where(a => a.OptionInfo.Durability >= 1000); var count = equip.Count(); if (count == 0) { break; } var item = equip.ElementAt(rnd.Next(count)); item.OptionInfo.Durability -= 1000; Send.ItemDurabilityUpdate(creature, item); Send.Notice(creature, Localization.Get("Repaired {0}"), item.Data.Name); break; } } }
public static void GiveItemFromOpenBox(GameSession session, Item item) { OpenItemBox box = item.Function.OpenItemBox; ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId); if (metadata == null) { session.Send(NoticePacket.Notice("No items found", NoticeType.Chat)); return; } if (box.AmountRequired > item.Amount) { return; } Inventory inventory = session.Player.Inventory; if (box.RequiredItemId > 0) { Item requiredItem = inventory.Items[box.RequiredItemId]; if (requiredItem == null) { return; } inventory.ConsumeItem(session, requiredItem.Uid, 1); } inventory.ConsumeItem(session, item.Uid, box.AmountRequired); Random rng = RandomProvider.Get(); // Receive one item from each drop group if (box.ReceiveOneItem) { foreach (DropGroup group in metadata.DropGroups) { //randomize the contents List <DropGroupContent> contentList = group.Contents.OrderBy(x => rng.Next()).ToList(); foreach (DropGroupContent dropContent in contentList) { List <Item> items = GetItemsFromDropGroup(dropContent, session.Player.Gender, session.Player.Job); foreach (Item newItem in items) { inventory.AddItem(session, newItem, true); } } } return; } // receive all items from each drop group foreach (DropGroup group in metadata.DropGroups) { foreach (DropGroupContent dropContent in group.Contents) { List <Item> items = GetItemsFromDropGroup(dropContent, session.Player.Gender, session.Player.Job); foreach (Item newItem in items) { inventory.AddItem(session, newItem, true); } } } }
public static MapPlayerSpawn GetRandomPlayerSpawn(int mapId) { List <MapPlayerSpawn> list = playerSpawns.GetValueOrDefault(mapId); return(list?.Count > 0 ? list[RandomProvider.Get().Next(list.Count)] : null); }
/// <summary> /// Uses the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetEntityId"></param> /// <returns></returns> public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { // Get target var mainTarget = attacker.Region.GetCreature(targetEntityId); if (mainTarget == null) { return(CombatSkillResult.InvalidTarget); } // Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, targetEntityId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); // Hit by chance var chance = attacker.AimMeter.GetAimChance(mainTarget); var rnd = RandomProvider.Get(); if (rnd.NextDouble() * 100 < chance) { aAction.Set(AttackerOptions.KnockBackHit2); // Get targets, incl. splash. // Splash happens from r5 onwards, but we'll base it on Var4, // which is the splash damage and first != 0 on r5. var targets = new HashSet <Creature>() { mainTarget }; if (skill.RankData.Var4 != 0) { var targetPosition = mainTarget.GetPosition(); var direction = attacker.GetPosition().GetDirection(targetPosition); targets.UnionWith(attacker.GetTargetableCreaturesInCone(targetPosition, direction, skill.RankData.Var5, skill.RankData.Var6)); } // Damage var mainDamage = this.GetDamage(attacker, skill); foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result | TargetOptions.CleanHit); tAction.Stun = TargetStun; cap.Add(tAction); // Damage var damage = mainDamage; // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // More damage with fire arrow // XXX: Does this affect the element? if (attacker.Temp.FireArrow) { damage *= FireBonus; } // Splash modifier if (target != mainTarget) { damage *= (skill.RankData.Var4 / 100f); } // Critical Hit var critChance = attacker.GetRightCritChance(target.Protection); CriticalHit.Handle(attacker, critChance, ref damage, tAction); // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage); // Conditions SkillHelper.HandleConditions(attacker, target, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction); // Natural Shield // Ignore delay reduction, as knock downs shouldn't be shortened NaturalShield.Handle(attacker, target, ref damage, tAction); // Deal with it! if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); SkillHelper.HandleInjury(attacker, target, damage); } // Knock down // If target is using a shield and defense, don't KD. var targetLeftHand = target.LeftHand; if (tAction.SkillId != SkillId.Defense || targetLeftHand == null || !targetLeftHand.IsShield) { // TODO: We have to calculate knockback distance right attacker.Shove(target, KnockBackDistance); tAction.Set(TargetOptions.KnockDownFinish); } // Aggro if (target == mainTarget) { target.Aggro(attacker); } if (target.IsDead) { tAction.Set(TargetOptions.Finished); if (target == mainTarget) { aAction.Set(AttackerOptions.KnockBackHit1); } } } } else { aAction.Set(AttackerOptions.Missed); } // Update current weapon SkillHelper.UpdateWeapon(attacker, mainTarget, ProficiencyGainType.Ranged, attacker.RightHand); // Reduce arrows if (attacker.Magazine != null && !ChannelServer.Instance.Conf.World.InfiniteArrows && !attacker.Magazine.HasTag("/unlimited_arrow/")) { attacker.Inventory.Decrement(attacker.Magazine); } // Disable fire arrow effect if (attacker.Temp.FireArrow) { Send.Effect(attacker, Effect.FireArrow, false); } // "Cancels" the skill // 800 = old load time? == aAction.Stun? Varies? Doesn't seem to be a stun. Send.SkillUse(attacker, skill.Info.Id, 800, 1); cap.Handle(); return(CombatSkillResult.Okay); }
public void CreateRegionAndWarp(Creature creature) { // Get duration var time = 5; if (IsEnabled("ShortSheepProtection")) { time = 3; } time *= Minute; // Create region var region = new DynamicRegion(118); ChannelServer.Instance.World.AddRegion(region); var rnd = RandomProvider.Get(); var sheepAmount = SheepAmount; // After x ms (success) var timer = SetTimeout(time, () => { // Unofficial, I think the msg also depends on how well you did. // Official >10: Thanks to my dilligent supervision, over 10 sheep are safe. Send.Notice(creature, NoticeType.MiddleSystem, L("The time is over, you did it.")); Send.RemoveQuestTimer(creature); creature.GiveKeyword("TirChonaill_Tutorial_Thinking"); creature.Warp(1, 27622, 42125); }); // Spawn sheep for (int i = 0; i < sheepAmount; ++i) { var pos = Center.GetRandomInRect(6000, 4000, rnd); var npc = new NPC(40001); // Sheep npc.Finish += (killed, killer) => { sheepAmount--; // Cancel if success is not possible anymore. if (sheepAmount < SheepMinAmount) { Send.Notice(creature, NoticeType.MiddleSystem, L("You've failed to save the sheep.")); Send.RemoveQuestTimer(creature); StopTimer(timer); creature.Warp(1, 27622, 42125); return; } Send.UpdateQuestTimer(creature, L("Remaining sheep: {0}"), sheepAmount); }; npc.Spawn(region.Id, pos.X, pos.Y); } // Spawn wolves for (int i = 0; i < WolfAmount; ++i) { SpawnWolf(region.Id, rnd); } // Warp to region and start visible timer creature.Warp(region.Id, 60000, 58000); Send.SetQuestTimer(creature, time, L("Protect the sheep from wolves"), L("Deadline: {0}"), L("Remaining sheep: {0}"), sheepAmount); }
/// <summary> /// Uses WM, attacking targets. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Use(Creature attacker, Skill skill, Packet packet) { var targetAreaId = packet.GetLong(); var unkInt1 = packet.GetInt(); var unkInt2 = packet.GetInt(); var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range); // Check targets if (targets.Count == 0) { Send.Notice(attacker, Localization.Get("There isn't a target nearby to use that on.")); Send.SkillUseSilentCancel(attacker); return; } // Create actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Info.Id, targetAreaId); aAction.Set(AttackerOptions.Result); cap.Add(aAction); var survived = new List <Creature>(); foreach (var target in targets) { target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Delay = 300; // Usually 300, sometimes 350? // Calculate damage and crit var damage = attacker.GetRndTotalDamage(); var critChance = attacker.CriticalBase; damage *= skill.RankData.Var1 / 100f; // Handle skills and reductions CriticalHit.Handle(attacker, critChance, ref damage, tAction); SkillHelper.HandleDefenseProtection(target, ref damage); Defense.Handle(aAction, tAction, ref damage); ManaShield.Handle(target, ref damage, tAction); // Clean Hit if not defended nor critical if (!tAction.Is(CombatActionType.Defended) && !tAction.Has(TargetOptions.Critical)) { tAction.Set(TargetOptions.CleanHit); } // Take damage if any is left if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Finish if dead, knock down if not defended if (target.IsDead) { tAction.Set(TargetOptions.KnockDownFinish); } else if (!tAction.Is(CombatActionType.Defended)) { tAction.Set(TargetOptions.KnockDown); } // Anger Management if (!target.IsDead) { survived.Add(target); } // Stun & knock back aAction.Stun = CombatMastery.GetAttackerStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); if (!tAction.Is(CombatActionType.Defended)) { tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; attacker.Shove(target, KnockbackDistance); } // Add action cap.Add(tAction); } // Only select a random aggro if there is no aggro yet, // WM only aggroes one target at a time. if (survived.Count != 0 && attacker.Region.CountAggro(attacker) < 1) { var rnd = RandomProvider.Get(); var aggroTarget = survived.Random(); aggroTarget.Aggro(attacker); } // Spin it~ Send.UseMotion(attacker, 8, 4); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); skill.Stacks = 0; }
/// <summary> /// Uses the skill /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetEntityId"></param> /// <returns></returns> public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { // Get Target var initTarget = attacker.Region.GetCreature(targetEntityId); // Check Target if (initTarget == null) { return(CombatSkillResult.InvalidTarget); } var attackerPos = attacker.StopMove(); var initTargetPos = initTarget.GetPosition(); // Check Range var range = (int)skill.RankData.Var2; if (!attacker.GetPosition().InRange(initTargetPos, range)) { return(CombatSkillResult.OutOfRange); } // Check for Collisions if (attacker.Region.Collisions.Any(attackerPos, initTargetPos)) { return(CombatSkillResult.InvalidTarget); } initTarget.StopMove(); // Effects Send.Effect(attacker, Effect.TheFakeSpiralSword, TheFakeSpiralSwordEffect.Attack, (DateTime.Now.Ticks / 10000), (byte)1); // Skill Use Send.SkillUseStun(attacker, skill.Info.Id, AttackerStun, 1); skill.Stacks = 0; // Prepare Combat Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, targetEntityId); aAction.Set(AttackerOptions.KnockBackHit1 | AttackerOptions.KnockBackHit2 | AttackerOptions.Result); cap.Add(aAction); aAction.Stun = AttackerStun; // Get Explosion Radius of Attack var explosionRadius = (int)skill.RankData.Var3 / 2; // Get Explosion Targets var targets = attacker.GetTargetableCreaturesAround(initTargetPos, explosionRadius); var rnd = RandomProvider.Get(); // Get Critical Hit var crit = false; if (attacker.Skills.Has(SkillId.CriticalHit, SkillRank.RF)) { var critChance = attacker.GetRightCritChance(0); crit = (rnd.Next(100) < critChance); } foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Delay = attackerPos.GetDistance(initTargetPos) / 2; cap.Add(tAction); // Damage var damage = (attacker.GetRndTotalDamage() * (skill.RankData.Var1 / 100f)); // Critical Hit if (crit) { CriticalHit.Handle(attacker, 100, ref damage, tAction); } // Defense and Prot SkillHelper.HandleDefenseProtection(target, ref damage); // Defense Defense.Handle(aAction, tAction, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction); // Heavy Stander HeavyStander.Handle(attacker, target, ref damage, tAction); // Apply Damage target.TakeDamage(tAction.Damage = damage, attacker); // Aggro target.Aggro(attacker); // Stun Time tAction.Stun = TargetStun; // Death and Knockback if (target.Is(RaceStands.KnockDownable)) { if (target.IsDead) { tAction.Set(TargetOptions.FinishingKnockDown); } else { tAction.Set(TargetOptions.KnockDown); } // Shove if (target == initTarget) { attacker.Shove(target, KnockbackDistance); } else { initTarget.Shove(target, KnockbackDistance); } } } aAction.Creature.Stun = aAction.Stun; cap.Handle(); // User can attack multiple times if attack isn't locked, which will cause them to freeze. // This is automatically unlocked by the skill after Use is finished. attacker.Lock(Locks.Attack); return(CombatSkillResult.Okay); }
/// <summary> /// Build a random square identity matrix. /// </summary> /// <param name="size">The size of the matrix.</param> /// <returns></returns> /*public static Matrix<double> Identity(int size) * { * return Matrix<double>.Build.DenseIdentity(size); * } */ /// <summary> /// Build a random square matrix where each entry is within the specified bounds. /// </summary> /// <param name="size">The size of the matrix.</param> /// <param name="bounds">The bounds for each entry.</param> /// <returns></returns> /*public static Matrix<double> Random(int size, Bounds bounds) * { * MatrixBuilder<double> matrixBuilder = Matrix<double>.Build; * Matrix<double> matrix = matrixBuilder.Dense(size, size, (i, j) => RandomProvider.NextDouble(bounds)); * * return matrix; * } */ /// <summary> /// /// </summary> /// <param name="size"></param> /// <param name="minValue">THe (inclusive) lower bound.</param> /// <param name="maxValue">The (inclusive) upper bound.</param> /// <returns></returns> public static Matrix <double> Random(int size, int minValue, int maxValue) { MatrixBuilder <double> matrixBuilder = Matrix <double> .Build; Matrix <double> matrix = matrixBuilder.Dense(size, size, (i, j) => RandomProvider.NextInt(minValue, maxValue)); return(matrix); }
/// <summary> /// Handles Heavy Stander bonuses and auto-defense, reducing damage /// and setting the appropriate options on tAction. Returns whether /// or not Heavy Stander pinged. /// </summary> /// <remarks> /// All active and passive Heavy Standers are checked in sequence, /// followed by the equipment, with the passive damage reduction /// stacking. It's unknown whether this is official, and assumedly /// no monsters have multiple Heavy Stander skills. /// The ping reduction is only applied once, no matter where it /// came from. /// </remarks> /// <param name="attacker"></param> /// <param name="target"></param> /// <param name="damage"></param> /// <param name="tAction"></param> public static bool Handle(Creature attacker, Creature target, ref float damage, TargetAction tAction) { var pinged = false; var rank = DefaultMsgRank; var rnd = RandomProvider.Get(); // Check skills for (int i = 0; i < Skills.Length; ++i) { // Check if skill exists and it's either in use or passive var skill = target.Skills.Get(Skills[i]); if (skill != null && (skill.Info.Id == SkillId.HeavyStanderPassive || skill.Has(SkillFlags.InUse))) { var damageReduction = skill.RankData.Var1; var activationChance = skill.RankData.Var3; // Apply damage reduction if (damageReduction > 0) { damage = Math.Max(1, damage - (damage / 100 * damageReduction)); } // Apply auto defense if (!pinged && rnd.Next(100) < activationChance) { pinged = true; rank = skill.Info.Rank; } } } // Check equipment if (!pinged) { var equipment = target.Inventory.GetMainEquipment(); for (int i = 0; i < equipment.Length; ++i) { var activationChance = equipment[i].Data.AutoDefenseMelee; if (activationChance > 0 && rnd.Next(100) < activationChance) { pinged = true; break; } } } // Notice, flag, and damage reduction if (pinged) { damage = Math.Max(1, damage / 2); tAction.EffectFlags |= EffectFlags.HeavyStander; var msg = ""; if (rank >= SkillRank.Novice && rank <= SkillRank.RA) { msg = rnd.Rnd(Lv1Msgs); } else if (rank >= SkillRank.R9 && rank <= SkillRank.R5) { msg = rnd.Rnd(Lv2Msgs); } else if (rank >= SkillRank.R4 && rank <= SkillRank.R1) { msg = rnd.Rnd(Lv3Msgs); } Send.Notice(attacker, msg); } return(pinged); }
public DiamondSquareCreator(RandomProvider randomProvider) { this.randomProvider = randomProvider; }
public static BigInteger Curve25519_GeneratePrivate(RandomProvider provider) => Support.GenerateRandom(provider, c_25519_order - 2) + 2;
public int GetWeight(RandomProvider rnd, int max) { return(rnd.Next(Weight, max + 100)); }
/// <summary> /// Handles using the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, true); var rnd = RandomProvider.Get(); // Create actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.Attacker, attacker, targetAreaId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); foreach (var target in targets) { // Check if hit var hitChance = this.GetHitChance(attacker, target, skill); if (rnd.Next(0, 100) > hitChance) { continue; } target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Delay = 300; // Calculate damage var damage = this.GetDamage(attacker, skill); // Handle skills and reductions CriticalHit.Handle(attacker, attacker.GetTotalCritChance(0), ref damage, tAction); SkillHelper.HandleDefenseProtection(target, ref damage); ManaShield.Handle(target, ref damage, tAction); // Clean Hit if not critical if (!tAction.Has(TargetOptions.Critical)) { tAction.Set(TargetOptions.CleanHit); } // Take damage if any is left if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Finish if dead, knock down if not defended if (target.IsDead) { tAction.Set(TargetOptions.KnockDownFinish); } else { tAction.Set(TargetOptions.KnockDown); } // Anger Management if (!target.IsDead) { target.Aggro(attacker); } // Stun & knock down tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; // Add action cap.Add(tAction); } Send.UseMotion(attacker, 10, 1); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); }
public override bool CanHandleCurrentContext() { return(RandomProvider.GetThreadRandom().NextDouble() > 0.6d && (Message.Text?.ToLower().Contains("nginx") ?? false)); }
public LockColorProvider() { var rnd = RandomProvider.Get(); _availableColors = new Queue <uint>(Colors.OrderBy(a => rnd.Next())); }
/// <summary> /// Prepares skill, goes straight to Use and starts playing. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> /// <param name="packet"></param> public bool Prepare(Creature creature, Skill skill, Packet packet) { var rnd = RandomProvider.Get(); // Check for instrument if (creature.RightHand == null || creature.RightHand.Data.Type != ItemType.Instrument) { return(false); } creature.StopMove(); // Get instrument type var instrumentType = this.GetInstrumentType(creature); // TODO: Make db for instruments with installable props. // Get mml from equipped score scroll if available. var mml = this.GetScore(creature); // Random score if no usable scroll was found. var rndScore = (mml == null ? this.GetRandomScore(rnd) : 0); // Quality seems to go from 0 (worst) to 3 (best). // TODO: Base quality on skills and score ranks. // The quality was apparently changed to a value from 0 to 100 // in the MusicQ update. We'll use the quality "rating" as fall- // back for the success messages and the training for now. var quality = rnd.Next(0, 100 + 1); // Sunday: Increase in success rate for instrument playing. // Another attempt if quality was bad, unofficial. if (quality < 50 && ErinnTime.Now.Month == ErinnMonth.Imbolic) { quality = rnd.Next(0, 100 + 1); } // Up quality by chance, based on Musical Knowledge var musicalKnowledgeSkill = creature.Skills.Get(SkillId.MusicalKnowledge); if (musicalKnowledgeSkill != null && rnd.Next(100) < musicalKnowledgeSkill.RankData.Var2) { quality += 25; } if (quality > 100) { quality = 100; } // Get quality for the effect, perfect play makes every sound perfect. var effectQuality = quality; if (ChannelServer.Instance.Conf.World.PerfectPlay) { effectQuality = 100; Send.ServerMessage(creature, Localization.Get("Perfect play is enabled, your performance will sound perfect.")); } // Reduce scroll's durability. if (mml != null) { creature.Inventory.ReduceDurability(creature.Magazine, DurabilityUse); } // Music effect and Use this.StartPlay(creature, skill, instrumentType, effectQuality, mml, rndScore); this.OnPlay(creature, skill, quality); Send.SkillUsePlayingInstrument(creature, skill.Info.Id, instrumentType, mml, rndScore); skill.State = SkillState.Used; // Special motion on highest quality. if (quality >= 100) { Send.UseMotion(creature, 88, 2, true); } // Give proficiency if (creature.RightHand.Durability != 0) { var amount = Item.GetProficiencyGain(creature.Age, ProficiencyGainType.Music); creature.Inventory.AddProficiency(creature.RightHand, amount); } // Called from Complete, once the song is finished. creature.Skills.Callback(skill.Info.Id, () => { Send.Notice(creature, this.GetRandomQualityMessage(quality)); this.AfterPlay(creature, skill, quality); }); return(true); }
/// <summary> /// Uses the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetEntityId"></param> /// <returns></returns> public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { // Get target var target = attacker.Region.GetCreature(targetEntityId); if (target == null) { return(CombatSkillResult.InvalidTarget); } // "Cancels" the skill // 800 = old load time? == aAction.Stun? Varies? Doesn't seem to be a stun. Send.SkillUse(attacker, skill.Info.Id, AttackerStun, 1); var chance = attacker.AimMeter.GetAimChance(target); var rnd = RandomProvider.Get().NextDouble() * 100; var successfulHit = (rnd < chance); // Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, targetEntityId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); // Target action if hit if (successfulHit) { target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Stun = TargetStun; cap.Add(tAction); // Damage // Formula unofficial, but it kinda matches what you would // expect from the skill, and what players believed the damage // to be, back in G2. // bonus = (100 - (6 - stacks) * 5 + rank, +var2 on last shot // I'm using rank instead of Var1, which goes from 1-15 in // AR2, so AR1 gets a little bonus as well, as AR1's Var1 and // 2 are 0. // With this formula, the bonus range (1st shot rF vs 5th shot // r1) is 76~110% for AR1, and 76~140% for AR2. var bonus = 100f - (6 - skill.Stacks) * 5f + (byte)skill.Info.Rank; if (skill.Stacks == 1) { bonus += skill.RankData.Var2; } var damage = attacker.GetRndRangedDamage() * (bonus / 100f); // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // More damage with fire arrow if (attacker.Temp.FireArrow) { damage *= FireBonus; } // Critical Hit var critChance = attacker.GetRightCritChance(target.Protection); CriticalHit.Handle(attacker, critChance, ref damage, tAction); // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage); // Defense Defense.Handle(aAction, tAction, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction); // Natural Shield var delayReduction = NaturalShield.Handle(attacker, target, ref damage, tAction); // Deal with it! if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); SkillHelper.HandleInjury(attacker, target, damage); } // Aggro target.Aggro(attacker); // Knock down on deadly if (target.Conditions.Has(ConditionsA.Deadly)) { tAction.Set(TargetOptions.KnockDown); } // Death/Knockback if (target.IsDead) { tAction.Set(TargetOptions.FinishingKnockDown); } else { // Insta-recover in knock down if (target.IsKnockedDown) { tAction.Stun = 0; } // Knock down if hit repeatedly else if (target.Stability < 30) { tAction.Set(TargetOptions.KnockDown); } // Normal stability reduction else { var stabilityReduction = StabilityReduction; // Reduce reduction, based on ping // According to the Wiki, "the Knockdown Gauge // [does not] build up", but it's still possible // to knock back with repeated hits. The stability // reduction is probably reduced, just like stun. if (delayReduction > 0) { stabilityReduction = (short)Math.Max(0, stabilityReduction - (stabilityReduction / 100 * delayReduction)); } target.Stability -= stabilityReduction; if (target.IsUnstable) { tAction.Set(TargetOptions.KnockBack); } } } // Knock Back if (tAction.IsKnockBack) { attacker.Shove(target, KnockBackDistance); } // Reduce stun, based on ping if (delayReduction > 0) { tAction.Stun = (short)Math.Max(0, tAction.Stun - (tAction.Stun / 100 * delayReduction)); } } // Update current weapon SkillHelper.UpdateWeapon(attacker, target, ProficiencyGainType.Ranged, attacker.RightHand); // Skill training if (skill.Info.Rank == SkillRank.RF) { skill.Train(1); // Try attacking with Arrow Revolver. } // Reduce arrows if (attacker.Magazine != null && !ChannelServer.Instance.Conf.World.InfiniteArrows && !attacker.Magazine.HasTag("/unlimited_arrow/")) { attacker.Inventory.Decrement(attacker.Magazine); } // Reduce stack skill.Stacks--; // Handle cap.Handle(); // Disable fire arrow effect if (attacker.Temp.FireArrow) { Send.Effect(attacker, Effect.FireArrow, false); } return(CombatSkillResult.Okay); }
protected override async Task Talk() { var challenger = NPC; var opponent = Player; if (challenger.Vars.Temp["inTrainerBattleWith"] == null) { challenger.Vars.Temp["inTrainerBattleWith"] = Player.EntityId; } else if (challenger.Vars.Temp["inTrainerBattleWith"] != Player.EntityId) { End("(" + challenger.Name + " is currently in battle.)"); } PrepareTrainers(challenger, Player); AssembleChallengerTeam(); AssemblePlayerTeam(); Creature cheerleader = null; if (Cheerleader != null) { cheerleader = challenger.Region.GetCreature(Cheerleader) as NPC; if (cheerleader != null) { cheerleader.TurnTo(Player.GetPosition()); PlaySong(cheerleader, "MML@t94l32>g+gf+fg+dd+eg+d+dd+g+dc+dg+c+cc+g+cc-cg+<ba+bn68a+g+a+l8.>a<aa8aa>a+8a<aa8aa>a+8>ccc8ccc+8ccc8cc<b8<<a>ed16e16l8gf+edf2a+2<a.>e.d16e16gf+edf2<f2l16>edefa+aa+>dc+4.<a+8a1<agaa+8aga+agaa+8aga+agaa+8aga+a>dc<a+agaa+gfgg+8gfg+gfgg+8gfg+gfgg+8gfg+fb+a+g+gfgg+g8.>d8.cdl8fedcd+1<f4d+fgfd+gg+4fgg+gfg+a4f+g+ag+f+aa+d+a+d+a+d+a+d+a+n51a+n51a+n51a+>d+l16n63a+>gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58gn58d+n58g<a+f8n46fg+8d+8f8g+gf4f8n46fg+8d+8f8gd+f4f8n46fg+8d+8f8gd+g+4g+4>c4d+4<g8d+g8.g8gfd+l8g.g+gd+16g.gg.g.g+g+.g.fd+fgd+f2g+2g.d+.g>c+c<a+g+f2a+g+gf<a+.l16>d+d+4<a+8.>gg4<a+8.>a+a+4g8.>d+d+4<a+4a+4g8.a+8.g+gd+4d+4a+8.g8ga+8<a8.>e8.del8gf+edf2a+2<a.>e.d16e16gf+edf2f2,r8l32rdc+cc-c<ba+ag+aa+bgf+feed+dc+dc+c<bbb+al16>aef+gef+geaef+gef+geaef+gef+geaef+gef+aa+b+gaa+gaa+gb+gaa+>cc+cn46c<gaa+gaa+gb+gaa+gaa+g<eaeaef+gaeaeaef+gefa+fa+faa+>d<fa+fa+faa+>d<eaeaef+gaeaeaef+gafa+fa+faa+>d<fa+fa+faa+>d<eaeaeaeaeaeaedefeaeaeaeae>fed<ag+aa+dadadadadadadagadadadadad>dc<a+agaa+cgcgcgcgcgcgcgfgcgcgcgcgcb+a+g+gfd+d>g4f4e4d+4d+a+d+a+d+a+ab+d+a+d+a+d+a+ab+cgcgcgcgcb+a+g+gfd+fc+g+c+g+c+g+c+g+c+g+c+g+c+g+bg+dadadadadabag+f+g+al8a+d+a+d+a+d+a+l1d+&d+&d+&d+&d+&d+&d+&d+&d+2&d+8l16<a+g+gfd+a+d+a+d+a+n37a+d+a+>c+c<a+g+gfd+a+d+a+d+a+n37a+d+a+>cc+d+c+c<a+d+a+d+a+d+a+d+a+d+a+d+a+d+a+d+a+c+g+c+g+c+g+c+g+c+g+c+g+c+b+a+g+d+a+d+a+d+a+d+a+d+a+d+a+d+a+d+a+c+g+c+g+c+g+c+g+c+>c+c<a+gg+a+>cl4d+c+cn34a+g+gf>d+d+<a+a+ggl8d+.d+d+16a+l2<ab+a+>d<ab+a+>d,r1l2.a&a8a+8al8&afl8.o6ccc8ccc+8ccc8cc<b8<<a>el16del8gf+edf2a+2<a.>e.d16e16gf+edf2<f2>a.e.a>d.fl16edfefedc+n58c+<a+2&a+l4edefedgfdcdd+dcdd+dd+efl2ga+d+l8gfd+gg+2g+gfg+a2ag+f+al4gd+a+gl8gd+gd+gd+gd+f4gd+fg16d+16fn46f4gd+fg+16g16fn46f4gd+fg16d+16fn46f4gd+fl16g+gf8<a+8>f8n46fg+gfd+l32dd+dd+l16fn46c4f8n46fg+gfd+l32dd+dd+l16fgf4f8n46fg+gfd+l32dd+dd+l16fn46c2>d+2<g8.g8.g8gfd+l8.gg+8ggg8l16gfd+l8.gg+8>d+a+l16g+gl8g+gfd+f2g+2d+.a+.g+16g16g+gfd+c+2c+c<a+g+g.l16d+a+4a+8.g>d+4d+8.n58g4g8.d+a+4g8.a+8.g+gd+2d+8.a+8.g+gd+1&d+1&d+2<<a8.>e8.del8gf+edf2f2;"); } } var rnd = RandomProvider.Get(); var regionId = challenger.RegionId; var challengerMonster = GetNextMonster(_challengerMonsters); var playerMonster = GetNextMonster(_playerMonsters); Task.Delay(FlashDelay + InitDelay / 2 + InitDelay * 1).ContinueWith(_ => SpawnMonster(challengerMonster, regionId, _challengerMonsterPos, _playerMonsterPos)); Task.Delay(FlashDelay + InitDelay / 2 + InitDelay * 2).ContinueWith(_ => SpawnMonster(playerMonster, regionId, _playerMonsterPos, _challengerMonsterPos)); Msg("<title name='NONE'/>You are challenged by<br/>{0}!<autopass duration='{1}'/>", challenger.Name, FlashDelay + InitDelay); Msg("<title name='NONE'/>{0} sent<br/>out {1}!<autopass duration='{2}'/>", challenger.Name, challengerMonster.Name, InitDelay); Msg("<title name='NONE'/>Go! {0}!<autopass duration='{1}'/>", playerMonster.Name, InitDelay); var options = ""; foreach (var skillId in Skills) { options += string.Format("<button title='{0}' keyword='@{1}'/>", GetSkillName(skillId), skillId); } //options += "<button title='Cancel' keyword='@cancel'/>"; var canceled = false; var result = BattleResult.None; while (true) { Msg("<title name='NONE'/>What will {0} do?" + options, playerMonster.Name); var action = await Select(); if (action == "@cancel") { canceled = true; break; } var playerSkillId = (SkillId)Enum.Parse(typeof(SkillId), action.Substring(1)); var challengerSkillId = SkillId.None; while ((challengerSkillId = rnd.Rnd(Skills)) == playerSkillId) { ; } Msg("<title name='NONE'/>{0} used<br/>{1}!<autopass duration='{2}'/>", playerMonster.Name, GetSkillName(playerSkillId), AttackDelay); Msg("<title name='NONE'/>The foe's {0} used<br/>{1}!<autopass duration='{2}'/>", challengerMonster.Name, GetSkillName(challengerSkillId), AttackDelay); PrepareAction(challengerSkillId, challengerMonster, playerMonster); PrepareAction(playerSkillId, playerMonster, challengerMonster); DoAction(challengerMonster, challengerSkillId, playerMonster, playerSkillId); var cm = challengerMonster; var pm = playerMonster; Task.Delay(AttackDelay / 2 + AttackDelay).ContinueWith(_ => { if (cm.Region != Region.Limbo) { if (!cm.IsDead && cm.GetPosition() != _challengerMonsterPos) { cm.Move(_challengerMonsterPos, false); } SharpMind(cm, pm, SkillId.None, SharpMindStatus.None); if (cm.Skills.ActiveSkill != null) { cm.Skills.CancelActiveSkill(); } } if (pm.Region != Region.Limbo) { if (!pm.IsDead && pm.GetPosition() != _playerMonsterPos) { pm.Move(_playerMonsterPos, false); } SharpMind(pm, cm, SkillId.None, SharpMindStatus.None); if (pm.Skills.ActiveSkill != null) { pm.Skills.CancelActiveSkill(); } } }); if (challengerMonster.IsDead) { Msg("<title name='NONE'/>The foe's {0} fainted!<autopass duration='{1}'/>", challengerMonster.Name, AttackDelay); Task.Delay(AttackDelay / 2 + AttackDelay + AttackDelay).ContinueWith(_ => UnspawnMonster(cm)); if ((challengerMonster = GetNextMonster(_challengerMonsters)) == null) { result = BattleResult.Won; } else { Msg("<title name='NONE'/>{0} sent<br/>out {1}!<autopass duration='{2}'/>", challenger.Name, challengerMonster.Name, InitDelay); Task.Delay(AttackDelay / 2 + AttackDelay + AttackDelay + InitDelay / 2).ContinueWith(_ => SpawnMonster(challengerMonster, regionId, _challengerMonsterPos, _playerMonsterPos)); } } else if (playerMonster.IsDead) { Msg("<title name='NONE'/>{0} fainted!<autopass duration='{1}'/>", playerMonster.Name, AttackDelay); Task.Delay(AttackDelay / 2 + AttackDelay + AttackDelay).ContinueWith(_ => UnspawnMonster(pm)); if ((playerMonster = GetNextMonster(_playerMonsters)) == null) { result = BattleResult.Lost; } else { Msg("<title name='NONE'/>Go! {0}!<autopass duration='{1}'/>", playerMonster.Name, InitDelay); Task.Delay(AttackDelay / 2 + AttackDelay + AttackDelay + InitDelay / 2).ContinueWith(_ => SpawnMonster(playerMonster, regionId, _playerMonsterPos, _challengerMonsterPos)); } } if (result != BattleResult.None) { break; } } if (result == BattleResult.Won) { var gold = rnd.Next(100, 1000); if (cheerleader != null) { StopSong(cheerleader); PlaySong(cheerleader, "MML@<gl16g.gl16.gf+4dc+16<ba8&a32a>f+d16<ab8&b32b>ge16c-c+8&c+32c+af+16c+<a8&a32>aa4<a8&a32a>f+d16<ab8&b32b>ge16c-c+8&c+32c+af+16c+<a8&a32>aa4<a8&a32a>f+d16<ab8&b32b>ge16c-c8&c32caf+16cd8&d32d>d<a+16gdf+16a>d2<ag16d<a>d16f+a2ge16c+<a8&a32a>f+d16<ab8&b32b>ge16c-c+8&c+32c+af+16c+<a8&a32>aa4<a8&a32a>f+d16<ab8&b32b>ge16c-c+8&c+32c+af+16c+<a8&a32>aa4<a8&a32a>f+d16<ab8&b32b>ge16c-c8&c32caf+16cd8&d32d>d<a+16gdf+16a>d2<ag16d<a>d16f+a2ge16c+,t160l16>e.el16.eef+16ga2<f+8&f+32df+4g8&g32eg4c+e16f+ab16n61a8&a32>c+e4<f+8&f+32df+4g8&g32eg4c+e16f+ab16n61a8&a32>c+e4<f+8&f+32df+4g8&g32eg4a8&a32fa4a+8&a+32ga+4>dc+16<a>dc+16<a>dc+16<af+a16>dc+<b16an61b16an61b16aef+16gf+8&f+32df+4g8&g32eg4c+e16f+ab16n61a8&a32>c+e4<f+8&f+32df+4g8&g32eg4c+e16f+ab16n61a8&a32>c+e4<f+8&f+32df+4g8&g32eg4a8&a32fa4a+8&a+32ga+4>dc+16<a>dc+16<a>dc+16<af+a16>dc+<b16an61b16an61b16aef+16g,l16>a.al16.aab16>c+d2<d8&d32<a>d4e8&e32c-e4f+8&f+32ga4e8&e32f+g4d8&d32<a>d4e8&e32c-e4f+8&f+32ga4e8&e32f+g4d8&d32<a>d4e8&e32c-e4f8&f32cf4g8&g32dg4f+1e1d8&d32<a>d4e8&e32c-e4f+8&f+32ga4e8&e32f+g4d8&d32<a>d4e8&e32c-e4f+8&f+32ga4e8&e32f+g4d8&d32<a>d4e8&e32c-e4f8&f32cf4g8&g32dg4f+1e1;"); } Msg("<title name='NONE'/>Player defeated<br/>{0}!<autopass duration='{1}'/>", challenger.Name, InitDelay); Msg("<title name='NONE'/>{0} got {1}g<br/>for winning!<autopass duration='{2}'/>", opponent.Name, gold, InitDelay); Task.Delay(InitDelay * 2).ContinueWith(_ => opponent.Inventory.Gold += gold); } else if (result == BattleResult.Lost) { Msg("<title name='NONE'/>Player was defeated<br/>by {0}!<autopass duration='{1}'/>", challenger.Name, InitDelay); Task.Delay(InitDelay).ContinueWith(_ => opponent.Inventory.Gold -= opponent.Inventory.Gold / 2); } if (result != BattleResult.Won && cheerleader != null) { StopSong(cheerleader); } if (result == BattleResult.Lost && cheerleader != null) { Send.UseMotion(cheerleader, 53, 3); } challenger.Vars.Temp["inTrainerBattleWith"] = null; opponent.Unlock(Locks.Move, true); var wait = (canceled ? 0 : AttackDelay / 2 + AttackDelay + AttackDelay + InitDelay); Task.Delay(wait).ContinueWith(_ => { if (challengerMonster != null && !challengerMonster.IsDead) { UnspawnMonster(challengerMonster); } if (playerMonster != null && !playerMonster.IsDead) { UnspawnMonster(playerMonster); } }); if (result == BattleResult.Won && cheerleader != null) { Task.Delay(wait + InitDelay).ContinueWith(_ => StopSong(cheerleader)); } if (canceled) { End("(Battle canceled.)"); } else { End("(The battle is over.)"); } }
/// <summary> /// Returns random number between 0.0 and 100.0. /// </summary> /// <returns></returns> protected double Random() { var rnd = RandomProvider.Get(); return(100 * rnd.NextDouble()); }
public override void OnCleared(Dungeon dungeon) { var rnd = RandomProvider.Get(); if (dungeon.CountPlayers() == 1) { var member = dungeon.Party[0]; var treasureChest = new TreasureChest(); // Bracelet int prefix = 0, suffix = 0; switch (rnd.Next(3)) { case 0: prefix = 206; break; // Snake case 1: prefix = 305; break; // Fine case 2: prefix = 303; break; // Rusty } switch (rnd.Next(3)) { case 0: suffix = 10504; break; // Topaz case 1: suffix = 10605; break; // Soldier case 2: suffix = 11206; break; // Fountain } treasureChest.Add(Item.CreateEnchanted(16015, prefix, suffix)); treasureChest.Add(Item.Create(id: 2000, amountMin: 570, amountMax: 2520)); // Gold treasureChest.Add(GetRandomTreasureItem(rnd)); // Random item dungeon.AddChest(treasureChest); member.GiveItemWithEffect(Item.CreateKey(70028, "chest")); } else { for (int i = 0; i < dungeon.Party.Count; ++i) { var member = dungeon.Party[i]; var treasureChest = new TreasureChest(); if (i == 0) { // Bracelet int prefix = 0, suffix = 0; switch (rnd.Next(3)) { case 0: suffix = 10504; break; // Topaz case 1: suffix = 10605; break; // Soldier case 2: suffix = 11205; break; // Water } treasureChest.Add(Item.CreateEnchanted(16015, prefix, suffix)); } treasureChest.Add(Item.Create(id: 2000, amountMin: 896, amountMax: 3600)); // Gold treasureChest.Add(GetRandomTreasureItem(rnd)); // Random item dungeon.AddChest(treasureChest); member.GiveItemWithEffect(Item.CreateKey(70028, "chest")); } } }
/// <summary> /// Returns random number between min and max-1. /// </summary> /// <param name="min">Inclusive lower bound</param> /// <param name="max">Exclusive upper bound</param> /// <returns></returns> protected int Random(int min, int max) { var rnd = RandomProvider.Get(); return(rnd.Next(min, max)); }
/// <summary> /// Uses the skill /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void UseSkill(Creature attacker, Skill skill, long targetEntityId) { var target = attacker.Region.GetCreature(targetEntityId); var attackerPos = attacker.GetPosition(); var targetPos = target.GetPosition(); // Check target + collisions if (target == null || attacker.Region.Collisions.Any(attackerPos, targetPos)) { Send.SkillUseSilentCancel(attacker); return; } // Stop movement attacker.StopMove(); target.StopMove(); Send.SkillUseEntity(attacker, skill.Info.Id, targetEntityId); skill.State = SkillState.Used; // Counter if (Counterattack.Handle(target, attacker)) { return; } // Defense/Protection decrease on target var debuffChance = (int)skill.RankData.Var6; var defDecrease = (int)skill.RankData.Var3; var protDecrease = (int)skill.RankData.Var4; var extra = new MabiDictionary(); extra.SetShort("NEW_DEF", (short)defDecrease); extra.SetShort("NEW_PROT", (short)protDecrease); extra.SetLong("DDP_CHAR", attacker.EntityId); extra.SetShort("DDP_SKILL", (short)skill.Info.Id); var rnd = RandomProvider.Get(); if (rnd.NextDouble() * 100 < debuffChance) { Send.Effect(target, Effect.SpinningUppercutDebuff, (short)skill.Info.Id, 0, defDecrease, protDecrease); target.Conditions.Activate(ConditionsC.DefProtectDebuff, extra); attacker.Temp.SpinningUppercutDebuffApplied = true; } // Prepare Combat Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, targetEntityId, skill.Info.Id); aAction.Set(AttackerOptions.Result); var tAction = new TargetAction(CombatActionType.TakeHit | CombatActionType.Attacker, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result | TargetOptions.FighterUnk); cap.Add(aAction, tAction); // Damage var damage = (attacker.GetRndFighterDamage() * (skill.RankData.Var1 / 100f)); // Chain Mastery Damage Bonus var chainMasterySkill = attacker.Skills.Get(SkillId.ChainMastery); var damageBonus = (chainMasterySkill == null ? 0 : chainMasterySkill.RankData.Var1); damage += damage * (damageBonus / 100f); // Master Title - Damage +20% if (attacker.Titles.SelectedTitle == skill.Data.MasterTitle) { damage += (damage * 0.2f); } // Critical Hit var critChance = attacker.GetRightCritChance(target.Protection); CriticalHit.Handle(attacker, critChance, ref damage, tAction); // Handle skills and reductions SkillHelper.HandleDefenseProtection(target, ref damage); HeavyStander.Handle(attacker, target, ref damage, tAction); SkillHelper.HandleConditions(attacker, target, ref damage); ManaShield.Handle(target, ref damage, tAction); // Apply Damage target.TakeDamage(tAction.Damage = damage, attacker); // Aggro target.Aggro(attacker); // Stun Times tAction.Stun = TargetStun; aAction.Stun = AttackerStun; // Death and Knockback if (target.IsDead) { if (target.Is(RaceStands.KnockDownable)) { tAction.Set(TargetOptions.FinishingKnockDown); attacker.Shove(target, KnockbackDistance); } else { tAction.Set(TargetOptions.Finished | TargetOptions.FinishingHit); } } else { if (!target.IsKnockedDown) { target.Stability -= StabilityReduction; } if (target.IsUnstable && target.Is(RaceStands.KnockDownable)) { tAction.Set(TargetOptions.KnockDown); attacker.Shove(target, KnockbackDistance); } } cap.Handle(); // Chain Progress to Stage 3 attacker.Temp.FighterChainStartTime = DateTime.Now; attacker.Temp.FighterChainLevel = 3; }
/// <summary> /// Returns a random value from the given ones. /// </summary> /// <param name="values"></param> protected T Rnd <T>(params T[] values) { var rnd = RandomProvider.Get(); return(rnd.Rnd(values)); }
/// <summary> /// Handles Natural Shield bonuses and auto-defense, reducing damage /// and setting the appropriate options on tAction. Returns the /// delay reduction and whether a ping occured. /// </summary> /// <remarks> /// All active and passive Natural Shields are checked in sequence, /// followed by the equipment. The first one found is the one that /// is used for the damage and delay reduction. It's unknown whether /// this is official behavior, but stacking them would be overkill. /// </remarks> /// <param name="attacker"></param> /// <param name="target"></param> /// <param name="damage"></param> /// <param name="tAction"></param> public static PassiveDefenseResult Handle(Creature attacker, Creature target, ref float damage, TargetAction tAction) { var pinged = false; var used = false; var damageReduction = 0f; var delayReduction = 0f; var rank = DefaultMsgRank; var rnd = RandomProvider.Get(); // Monsters with the /beatable_only/ tag don't take damage from // anything but pillows. if (target.HasTag("/beatable_only/")) { damage = 1; } // Check skills for (int i = 0; i < Skills.Length; ++i) { // Check if skill exists and it's either in use or passive var skill = target.Skills.Get(Skills[i]); if (skill != null && (skill.Info.Id == SkillId.NaturalShieldPassive || skill.Has(SkillFlags.InUse))) { damageReduction = skill.RankData.Var1; delayReduction = skill.RankData.Var2; pinged = (skill.RankData.Var3 == 1); rank = skill.Info.Rank; used = true; break; } } // Check equipment if (!used) { var equipment = target.Inventory.GetMainEquipment(); foreach (var item in equipment) { var chance = item.Data.AutoDefenseRanged; // Add upgrades chance += item.MetaData1.GetFloat("IM_RNG") * 100; if (chance > 0) { if (used = pinged = (rnd.Next(100) < chance)) { damageReduction = DefaultDamageReduction; delayReduction = DefaultDelayReduction; break; } } } } // Notice and flag if (pinged) { tAction.EffectFlags |= EffectFlags.NaturalShield; var msg = ""; if (rank >= SkillRank.Novice && rank <= SkillRank.RA) { msg = rnd.Rnd(Lv1Msgs); } else if (rank >= SkillRank.R9 && rank <= SkillRank.R2) { msg = rnd.Rnd(Lv2Msgs); } else if (rank == SkillRank.R1) { msg = rnd.Rnd(Lv3Msgs); } Send.Notice(attacker, msg); } // Apply damage reduction and return delay reduction if (damageReduction > 0) { damage = Math.Max(1, damage - (damage / 100 * damageReduction)); } return(new PassiveDefenseResult(pinged, delayReduction)); }
/// <summary> /// Handles Mana Deflector bonuses and auto-defense, reducing damage /// and setting the appropriate options on tAction. Returns stun /// reduction modifier. /// </summary> /// <remarks> /// All active and passive Mana Deflectors are checked in sequence, /// followed by the equipment. The first one found is the one that /// is used for the damage and delay reduction. It's unknown whether /// this is official behavior, but stacking them would be overkill. /// </remarks> /// <param name="attacker"></param> /// <param name="target"></param> /// <param name="damage"></param> /// <param name="tAction"></param> public static float Handle(Creature attacker, Creature target, ref float damage, TargetAction tAction) { var pinged = false; var used = false; var damageReduction = 0f; var delayReduction = 0f; var rank = DefaultMsgRank; var rnd = RandomProvider.Get(); // Dark Lord is immune to melee and magic damage, // like a R1 passive defense, but he doesn't ping. if (target.HasTag("/darklord/") && !target.HasTag("/darklord/darklord2/")) { damage = 1; return(delayReduction); } // Check skills for (int i = 0; i < Skills.Length; ++i) { // Check if skill exists and it's either in use or passive var skill = target.Skills.Get(Skills[i]); if (skill != null && (skill.Info.Id == SkillId.ManaDeflectorPassive || skill.Has(SkillFlags.InUse))) { damageReduction = skill.RankData.Var1; delayReduction = skill.RankData.Var2; pinged = (skill.RankData.Var3 == 1); rank = skill.Info.Rank; used = true; break; } } // Check equipment if (!used) { var equipment = target.Inventory.GetMainEquipment(); foreach (var item in equipment) { var chance = item.Data.AutoDefenseMagic; // Add upgrades chance += item.MetaData1.GetFloat("IM_MGC") * 100; if (chance > 0) { if (used = pinged = (rnd.Next(100) < chance)) { damageReduction = DefaultDamageReduction; delayReduction = DefaultDelayReduction; break; } } } } // Notice and flag if (pinged) { tAction.EffectFlags |= EffectFlags.ManaDeflector; var msg = ""; if (rank >= SkillRank.Novice && rank <= SkillRank.RA) { msg = rnd.Rnd(Lv1Msgs); } else if (rank >= SkillRank.R9 && rank <= SkillRank.R2) { msg = rnd.Rnd(Lv2Msgs); } else if (rank == SkillRank.R1) { msg = rnd.Rnd(Lv3Msgs); } Send.Notice(attacker, msg); } // Apply damage reduction and return delay reduction if (damageReduction > 0) { damage = Math.Max(1, damage - (damage / 100 * damageReduction)); } return(delayReduction); }
public WorldGenElevation(Graph graph, float clipPercentile) { this.graph = graph; this.clipPercentile = clipPercentile; random = new SeededRandomProvider(graph.seed); }
public override void Handle(GameSession session, PacketReader packet) { bool mapIsHome = session.Player.MapId == (int)Map.PrivateResidence; UGCMapMetadata ugcMapMetadata = UGCMapMetadataStorage.GetMetadata(session.Player.MapId); List <byte> plots = new(); if (ugcMapMetadata != null) { plots = ugcMapMetadata.Groups.Select(x => x.Id).ToList(); } List <Home> homes; if (mapIsHome) { Home home = GameServer.HomeManager.GetHomeById(session.Player.VisitingHomeId); if (home == null) { session.Send(ResponseLoadUGCMapPacket.LoadUGCMap(false)); return; } homes = new() { home }; session.Send(ResponseLoadUGCMapPacket.LoadUGCMap(mapIsHome, home, session.Player.IsInDecorPlanner)); // Find spawning coords for home int cubePortalId = 50400190; List <Cube> portals = home.FurnishingInventory.Values.Where(x => x.Item != null && x.Item.Id == cubePortalId).ToList(); CoordF coord; CoordF rotation; if (portals.Count > 0) { Cube portal = portals.OrderBy(x => RandomProvider.Get().Next()).Take(1).First(); coord = portal.CoordF; coord.Z += 1; rotation = portal.Rotation; rotation.Z -= 90; } else { byte homeSize = (byte)(home.Size - 1); int x = -1 * Block.BLOCK_SIZE * homeSize; coord = CoordF.From(x, x, 151); rotation = CoordF.From(0, 0, 0); } session.Player.SavedCoord = coord; session.Player.SavedRotation = rotation; session.Player.SafeBlock = coord; session.Player.InstanceId = home.InstanceId; } else { homes = GameServer.HomeManager.GetPlots(session.Player.MapId); session.Send(ResponseLoadUGCMapPacket.LoadUGCMap(mapIsHome)); } List <Cube> cubes = new(); if (!session.Player.IsInDecorPlanner) { homes.ForEach(h => { int plotNumber = mapIsHome ? 1 : h.PlotNumber; cubes.AddRange(h.FurnishingInventory.Values.Where(x => x.Item.Id != 0 && x.PlotNumber == plotNumber).ToList()); }); } session.Send(SendCubesPacket.LoadPlots(homes, session.Player.MapId)); session.Send(SendCubesPacket.LoadCubes(cubes)); session.Send(SendCubesPacket.LoadAvailablePlots(homes, plots)); session.Send(SendCubesPacket.Expiration(homes.Where(x => x.PlotNumber != 0).ToList())); session.Send("6D 00 12 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); // send ugc }