예제 #1
0
파일: FirstAid.cs 프로젝트: xKamuna/aura-1
        /// <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);
        }
예제 #2
0
    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.");
        }
    }
예제 #3
0
 /// <summary>
 /// Class constructor
 /// </summary>
 public Provably()
 {
     mRandom = new RandomProvider();
 }
예제 #4
0
파일: Fountain.cs 프로젝트: Vinna/aura-old
        /// <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;
            }
            }
        }
예제 #5
0
    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);
                }
            }
        }
    }
예제 #6
0
        public static MapPlayerSpawn GetRandomPlayerSpawn(int mapId)
        {
            List <MapPlayerSpawn> list = playerSpawns.GetValueOrDefault(mapId);

            return(list?.Count > 0 ? list[RandomProvider.Get().Next(list.Count)] : null);
        }
예제 #7
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 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);
        }
예제 #8
0
    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);
    }
예제 #9
0
        /// <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;
        }
예제 #10
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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
 public DiamondSquareCreator(RandomProvider randomProvider)
 {
     this.randomProvider = randomProvider;
 }
예제 #14
0
 public static BigInteger Curve25519_GeneratePrivate(RandomProvider provider) => Support.GenerateRandom(provider, c_25519_order - 2) + 2;
예제 #15
0
파일: NPCObject.cs 프로젝트: putao520/mir2
 public int GetWeight(RandomProvider rnd, int max)
 {
     return(rnd.Next(Weight, max + 100));
 }
예제 #16
0
파일: Stomp.cs 프로젝트: Vinna/aura
        /// <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);
        }
예제 #17
0
 public override bool CanHandleCurrentContext()
 {
     return(RandomProvider.GetThreadRandom().NextDouble() > 0.6d && (Message.Text?.ToLower().Contains("nginx") ?? false));
 }
예제 #18
0
            public LockColorProvider()
            {
                var rnd = RandomProvider.Get();

                _availableColors = new Queue <uint>(Colors.OrderBy(a => rnd.Next()));
            }
예제 #19
0
        /// <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);
        }
예제 #20
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 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);
        }
예제 #21
0
    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.)");
        }
    }
예제 #22
0
        /// <summary>
        /// Returns random number between 0.0 and 100.0.
        /// </summary>
        /// <returns></returns>
        protected double Random()
        {
            var rnd = RandomProvider.Get();

            return(100 * rnd.NextDouble());
        }
예제 #23
0
    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"));
            }
        }
    }
예제 #24
0
        /// <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));
        }
예제 #25
0
        /// <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;
        }
예제 #26
0
        /// <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));
        }
예제 #27
0
        /// <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));
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
 public WorldGenElevation(Graph graph, float clipPercentile)
 {
     this.graph          = graph;
     this.clipPercentile = clipPercentile;
     random = new SeededRandomProvider(graph.seed);
 }
예제 #30
0
    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
    }