Ejemplo n.º 1
0
    /// <summary>
    /// Get the coordinates of the skill's effect, if needed change the offset to match the direction of the player.
    /// For skills that paint the ground, match the correct height.
    /// </summary>
    private static List <CoordF> GetEffectCoords(SkillCast skillCast, int mapId, int attackIndex)
    {
        SkillAttack          skillAttack        = skillCast.SkillAttack;
        List <MagicPathMove> cubeMagicPathMoves = new();
        List <MagicPathMove> magicPathMoves     = new();

        if (skillAttack.CubeMagicPathId != 0)
        {
            cubeMagicPathMoves.AddRange(MagicPathMetadataStorage.GetMagicPath(skillAttack.CubeMagicPathId)?.MagicPathMoves ?? new());
        }

        if (skillAttack.MagicPathId != 0)
        {
            magicPathMoves.AddRange(MagicPathMetadataStorage.GetMagicPath(skillAttack.MagicPathId)?.MagicPathMoves ?? new());
        }

        int skillMovesCount = cubeMagicPathMoves.Count + magicPathMoves.Count;

        List <CoordF> effectCoords = new();

        if (skillMovesCount <= 0)
        {
            effectCoords.Add(skillCast.Position);
            return(effectCoords);
        }

        // TODO: Handle case where magicPathMoves and cubeMagicPathMoves counts are > 0
        // Basically do the next if, with the later for loop

        if (magicPathMoves.Count > 0)
        {
            MagicPathMove magicPathMove = magicPathMoves[attackIndex];

            IFieldActor <NpcMetadata> parentSkillTarget = skillCast.ParentSkill.Target;
            if (parentSkillTarget is not null)
            {
                effectCoords.Add(parentSkillTarget.Coord);

                return(effectCoords);
            }

            // Rotate the offset coord and distance based on the look direction
            CoordF rotatedOffset = CoordF.From(magicPathMove.FireOffsetPosition.Length(), skillCast.LookDirection);
            CoordF distance      = CoordF.From(magicPathMove.Distance, skillCast.LookDirection);

            // Create new effect coord based on offset rotation and distance
            effectCoords.Add(rotatedOffset + distance + skillCast.Position);

            return(effectCoords);
        }

        // Adjust the effect on the destination/cube
        foreach (MagicPathMove cubeMagicPathMove in cubeMagicPathMoves)
        {
            CoordF offSetCoord = cubeMagicPathMove.FireOffsetPosition;

            // If false, rotate the offset based on the look direction. Example: Wizard's Tornado
            if (!cubeMagicPathMove.IgnoreAdjust)
            {
                // Rotate the offset coord based on the look direction
                CoordF rotatedOffset = CoordF.From(offSetCoord.Length(), skillCast.LookDirection);

                // Create new effect coord based on offset rotation and source coord
                effectCoords.Add(rotatedOffset + skillCast.Position);
                continue;
            }

            offSetCoord += Block.ClosestBlock(skillCast.Position);

            CoordS tempBlockCoord = offSetCoord.ToShort();

            // Set the height to the max allowed, which is one block above the cast coord.
            tempBlockCoord.Z += Block.BLOCK_SIZE * 2;

            // Find the first block below the effect coord
            int distanceToNextBlockBelow = MapMetadataStorage.GetDistanceToNextBlockBelow(mapId, offSetCoord.ToShort(), out MapBlock blockBelow);

            // If the block is null or the distance from the cast effect Z height is greater than two blocks, continue
            if (blockBelow is null || distanceToNextBlockBelow > Block.BLOCK_SIZE * 2)
            {
                continue;
            }

            // If there is a block above, continue
            if (MapMetadataStorage.BlockAboveExists(mapId, blockBelow.Coord))
            {
                continue;
            }

            // If block is liquid, continue
            if (MapMetadataStorage.IsLiquidBlock(blockBelow))
            {
                continue;
            }

            // Since this is the block below, add 150 units to the Z coord so the effect is above the block
            offSetCoord    = blockBelow.Coord.ToFloat();
            offSetCoord.Z += Block.BLOCK_SIZE;

            effectCoords.Add(offSetCoord);
        }

        return(effectCoords);
    }