Skip to content

Commit f9fb419

Browse files
authored
Merge pull request #30 from flightlex/master
level length
2 parents 21ed109 + 90b16cf commit f9fb419

File tree

8 files changed

+147
-6
lines changed

8 files changed

+147
-6
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.IO;
2+
using System.Net;
3+
using FluentAssertions;
4+
using GeometryDashAPI.Levels;
5+
using GeometryDashAPI.Server;
6+
using GeometryDashAPI.Server.Responses;
7+
using NUnit.Framework;
8+
9+
namespace GeometryDashAPI.Tests;
10+
11+
[TestFixture]
12+
public class LevelLengthTests
13+
{
14+
[TestCase("12034598_Conclusion", 57)]
15+
[TestCase("28755513_TheFinalLair", 154)]
16+
[TestCase("116631_XmasParty", 87)]
17+
public void Test(string fileName, int expectedSeconds)
18+
{
19+
var responseBody = File.ReadAllText(Path.Combine("data", "levels", fileName));
20+
var response = new ServerResponse<LevelResponse>(HttpStatusCode.OK, responseBody);
21+
var level = new Level(response.GetResultOrDefault().Level.LevelString, compressed: true);
22+
level.LevelLength.TotalSeconds.Should().BeApproximately(expectedSeconds, precision: 1);
23+
}
24+
}
Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
using GeometryDashAPI.Attributes;
1+
using System;
2+
using GeometryDashAPI.Attributes;
23
using GeometryDashAPI.Levels.Enums;
3-
using GeometryDashAPI.Levels.GameObjects.Default;
44

55
namespace GeometryDashAPI.Levels.GameObjects.Specific
66
{
7+
/// <summary>
8+
/// Represents the id of the speed block.<br/><br/>
9+
/// Not to be confused with <see cref="SpeedType"/>.<br/>
10+
/// Because it is responsible for a specific speed, instead of a specific block id
11+
/// </summary>
712
public enum SpeedBlockId
813
{
914
Orange = 200,
@@ -14,26 +19,59 @@ public enum SpeedBlockId
1419
}
1520

1621
[GameBlock(200, 201, 202, 203, 1334)]
17-
public class SpeedBlock : Block
22+
public class SpeedBlock : Portal
1823
{
1924
[GameProperty("24", (short)Layer.B2)] protected override short zLayer { get; set; } = (short)Layer.B2;
2025
[GameProperty("25", -6)] public override int ZOrder { get; set; } = -6;
2126

22-
[GameProperty("13", true, true)]
23-
public bool Using { get; set; } = true;
24-
2527
public SpeedBlockId BlockType
2628
{
2729
get => (SpeedBlockId)Id;
2830
set => Id = (int)value;
2931
}
3032

33+
public SpeedType SpeedType
34+
{
35+
get => FromBlockIdToSpeedType(BlockType);
36+
set => BlockType = FromSpeedTypeToBlockId(value);
37+
}
38+
3139
public SpeedBlock() : base(201)
3240
{
3341
}
3442

3543
public SpeedBlock(SpeedBlockId type) : base((int)type)
3644
{
3745
}
46+
47+
public SpeedBlock(SpeedType type) : base((int)FromSpeedTypeToBlockId(type))
48+
{
49+
}
50+
51+
public static SpeedType FromBlockIdToSpeedType(SpeedBlockId id)
52+
{
53+
return id switch
54+
{
55+
SpeedBlockId.Orange => SpeedType.Half,
56+
SpeedBlockId.Default => SpeedType.Default,
57+
SpeedBlockId.Green => SpeedType.X2,
58+
SpeedBlockId.Purple => SpeedType.X3,
59+
SpeedBlockId.Red => SpeedType.X4,
60+
_ => throw new ArgumentOutOfRangeException(nameof(id), id, null)
61+
};
62+
}
63+
64+
public static SpeedBlockId FromSpeedTypeToBlockId(SpeedType speedType)
65+
{
66+
return speedType switch
67+
{
68+
SpeedType.Half => SpeedBlockId.Orange,
69+
SpeedType.Default => SpeedBlockId.Default,
70+
SpeedType.X2 => SpeedBlockId.Green,
71+
SpeedType.X3 => SpeedBlockId.Purple,
72+
SpeedType.X4 => SpeedBlockId.Red,
73+
_ => throw new ArgumentOutOfRangeException(nameof(speedType), speedType, null)
74+
};
75+
}
3876
}
3977
}
File renamed without changes.
File renamed without changes.

GeometryDashAPI/Levels/Level.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public Guidelines Guidelines
2323
set => Options.Guidelines = value;
2424
}
2525

26+
public TimeSpan LevelLength => Levels.LevelLength.Measure(this);
27+
2628
public int CountBlock => Blocks.Count;
2729
public int CountColor => Options.Colors.Count;
2830

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Linq;
3+
using GeometryDashAPI.Levels.GameObjects.Specific;
4+
5+
namespace GeometryDashAPI.Levels
6+
{
7+
public static class LevelLength
8+
{
9+
public static TimeSpan Measure(Level level)
10+
{
11+
var maxX = level.Blocks.Max(x => x.PositionX);
12+
var portals = GetSpeedBlocks(level);
13+
14+
var seconds = 0d;
15+
var i = 1;
16+
for (; i < portals.Length; i++)
17+
seconds += (portals[i].PositionX - portals[i - 1].PositionX) / portals[i - 1].SpeedType.GetSpeed();
18+
19+
var final = Math.Min(i, portals.Length - 1);
20+
var total = seconds + (maxX - portals[final].PositionX) / portals[final].SpeedType.GetSpeed();
21+
22+
return TimeSpan.FromSeconds(total);
23+
}
24+
25+
private static SpeedBlock[] GetSpeedBlocks(Level level)
26+
{
27+
return new[] { new SpeedBlock(level.Options.PlayerSpeed) }
28+
.Concat(level.Blocks.OfType<SpeedBlock>()
29+
.Where(x => x.Checked)
30+
.OrderBy(x => x.PositionX)
31+
).ToArray();
32+
}
33+
}
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using GeometryDashAPI.Levels.Enums;
2+
3+
namespace GeometryDashAPI.Levels
4+
{
5+
public static class LevelSpeed
6+
{
7+
public const double Half = 251.16;
8+
public const double Default = 311.58;
9+
public const double X2 = 387.42;
10+
public const double X3 = 468;
11+
public const double X4 = 576;
12+
13+
public static double GetSpeed(this SpeedType speedType)
14+
{
15+
return speedType switch
16+
{
17+
SpeedType.Half => Half,
18+
SpeedType.Default => Default,
19+
SpeedType.X2 => X2,
20+
SpeedType.X3 => X3,
21+
SpeedType.X4 => X4
22+
};
23+
}
24+
}
25+
}

GeometryDashAPI/Levels/Portal.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using GeometryDashAPI.Attributes;
2+
using GeometryDashAPI.Levels.GameObjects.Default;
3+
4+
namespace GeometryDashAPI.Levels
5+
{
6+
public class Portal : Block
7+
{
8+
[GameProperty("13", true, true)] public bool Checked { get; set; }
9+
10+
public Portal()
11+
{
12+
}
13+
14+
public Portal(int id) : base(id)
15+
{
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)