diff --git a/OngekiFumenEditor/Base/OngekiObjects/Bell.cs b/OngekiFumenEditor/Base/OngekiObjects/Bell.cs index 37a56b72..c0a61a10 100644 --- a/OngekiFumenEditor/Base/OngekiObjects/Bell.cs +++ b/OngekiFumenEditor/Base/OngekiObjects/Bell.cs @@ -34,7 +34,8 @@ public BulletPallete ReferenceBulletPallete NotifyOfPropertyChange(() => TypeValue); NotifyOfPropertyChange(() => TargetValue); NotifyOfPropertyChange(() => ShooterValue); - NotifyOfPropertyChange(() => SizeValue); + NotifyOfPropertyChange(() => RandomOffsetRange); + NotifyOfPropertyChange(() => SizeValue); } } @@ -49,7 +50,8 @@ private void ReferenceBulletPallete_PropertyChanged(object sender, System.Compon case nameof(BulletPallete.ShooterValue): case nameof(BulletPallete.SizeValue): case nameof(BulletPallete.Speed): - NotifyOfPropertyChange(e.PropertyName); + case nameof(BulletPallete.RandomOffsetRange): + NotifyOfPropertyChange(e.PropertyName); break; } } @@ -59,7 +61,11 @@ private void ReferenceBulletPallete_PropertyChanged(object sender, System.Compon [ObjectPropertyBrowserShow] public float Speed => ReferenceBulletPallete?.Speed ?? default; - [ObjectPropertyBrowserAlias("BPL." + nameof(StrID))] + [ObjectPropertyBrowserAlias("BPL." + nameof(RandomOffsetRange))] + [ObjectPropertyBrowserShow] + public float RandomOffsetRange => ReferenceBulletPallete?.RandomOffsetRange ?? default; + + [ObjectPropertyBrowserAlias("BPL." + nameof(StrID))] [ObjectPropertyBrowserShow] public string StrID => ReferenceBulletPallete?.StrID; diff --git a/OngekiFumenEditor/Base/OngekiObjects/BulletPallete.cs b/OngekiFumenEditor/Base/OngekiObjects/BulletPallete.cs index d1ae29cc..343167f6 100644 --- a/OngekiFumenEditor/Base/OngekiObjects/BulletPallete.cs +++ b/OngekiFumenEditor/Base/OngekiObjects/BulletPallete.cs @@ -1,6 +1,7 @@ using OngekiFumenEditor.Base.EditorObjects; using OngekiFumenEditor.Base.OngekiObjects.BulletPalleteEnums; using OngekiFumenEditor.Base.OngekiObjects.Lane; +using System; using System.Linq; using System.Windows.Media; @@ -8,6 +9,8 @@ namespace OngekiFumenEditor.Base.OngekiObjects { public class BulletPallete : OngekiObjectBase { + public static int RandomSeed { get; set; } = DateTime.Now.ToString().GetHashCode(); + public double CalculateToXGridTotalUnit(IBulletPalleteReferencable refObject, OngekiFumen fumen) { double xGridTotalUnit; @@ -28,7 +31,16 @@ public double CalculateToXGridTotalUnit(IBulletPalleteReferencable refObject, On break; } - return xGridTotalUnit; + var randomOffset = 0; + if (RandomOffsetRange > 0) + { + //不想用Random类,直接异或计算吧 + var seed = (60045 * Id + 123) % 2147483648 * Id ^ Id; + var r = RandomOffsetRange; + randomOffset = (-r) + (int)(seed % (r - (-r) + 1)); + } + + return xGridTotalUnit + randomOffset; } public double CalculateFromXGridTotalUnit(IBulletPalleteReferencable refObject, OngekiFumen fumen) @@ -111,6 +123,17 @@ public int PlaceOffset } } + private int randomOffsetRange = default; + public int RandomOffsetRange + { + get { return randomOffsetRange; } + set + { + randomOffsetRange = value; + NotifyOfPropertyChange(() => RandomOffsetRange); + } + } + private Target targetValue = Target.FixField; public Target TargetValue { @@ -149,7 +172,7 @@ public float Speed public bool IsEnableSoflan => TargetValue != Target.Player; - public override string ToString() => $"{base.ToString()} StrID[{StrID}] Speed[{Speed:F3}] ShooterValue[{ShooterValue}] TargetValue[{TargetValue}] SizeValue[{SizeValue}] TypeValue[{TypeValue}] EditorName[{EditorName}] PlaceOffset[{PlaceOffset}]"; + public override string ToString() => $"{base.ToString()} StrID[{StrID}] Speed[{Speed:F3}] ShooterValue[{ShooterValue}] TargetValue[{TargetValue}] SizeValue[{SizeValue}] TypeValue[{TypeValue}] EditorName[{EditorName}] PlaceOffset[{PlaceOffset}] RandomOffsetRange[{RandomOffsetRange}]"; public static string CommandName => "BPL"; public override string IDShortName => CommandName; @@ -168,6 +191,7 @@ public override void Copy(OngekiObjectBase fromObj) ShooterValue = fromBpl.ShooterValue; Speed = fromBpl.Speed; TargetValue = fromBpl.TargetValue; + RandomOffsetRange = fromBpl.RandomOffsetRange; } } } diff --git a/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/TargetImpl/OngekiObjects/BulletBell/BulletPalleteReferencableBatchDrawTargetBase.cs b/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/TargetImpl/OngekiObjects/BulletBell/BulletPalleteReferencableBatchDrawTargetBase.cs index ba9880e0..f1153a01 100644 --- a/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/TargetImpl/OngekiObjects/BulletBell/BulletPalleteReferencableBatchDrawTargetBase.cs +++ b/OngekiFumenEditor/Modules/FumenVisualEditor/Graphics/Drawing/TargetImpl/OngekiObjects/BulletBell/BulletPalleteReferencableBatchDrawTargetBase.cs @@ -164,7 +164,8 @@ void _Draw(T obj) return; var fromX = convertToX(bulletPallateRefObj.ReferenceBulletPallete?.CalculateFromXGridTotalUnit(bulletPallateRefObj, target.Editor.Fumen) ?? obj.XGrid.TotalUnit); - var toX = convertToX(bulletPallateRefObj.ReferenceBulletPallete?.CalculateToXGridTotalUnit(bulletPallateRefObj, target.Editor.Fumen) ?? obj.XGrid.TotalUnit); + var toXUnit = bulletPallateRefObj.ReferenceBulletPallete?.CalculateToXGridTotalUnit(bulletPallateRefObj, target.Editor.Fumen) ?? obj.XGrid.TotalUnit; + var toX = convertToX(toXUnit); var timeX = MathUtils.CalculateXFromTwoPointFormFormula(currentTime, fromX, fromTime, toX, toTime); if (!(target.Rect.MinX <= timeX && timeX <= target.Rect.MaxX)) diff --git a/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/CommandImpl/Objects/BulletPalleteCommandParser.cs b/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/CommandImpl/Objects/BulletPalleteCommandParser.cs index 49fd5a5c..9fc14867 100644 --- a/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/CommandImpl/Objects/BulletPalleteCommandParser.cs +++ b/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/CommandImpl/Objects/BulletPalleteCommandParser.cs @@ -25,7 +25,8 @@ public void ParseAndApply(OngekiFumen fumen, string[] seg) bpl.SizeValue = Enum.Parse(map["Size"]); bpl.TypeValue = Enum.Parse(map["Type"]); bpl.Speed = float.Parse(map["Speed"]); - bpl.PlaceOffset = int.Parse(map["PlaceOffset"]); + bpl.RandomOffsetRange = int.Parse(map["RandomOffsetRange"]); + bpl.PlaceOffset = int.Parse(map["PlaceOffset"]); fumen.AddObject(bpl); } diff --git a/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/DefaultNyagekiFumenFormatter.cs b/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/DefaultNyagekiFumenFormatter.cs index 7c75b2a5..7d7aa363 100644 --- a/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/DefaultNyagekiFumenFormatter.cs +++ b/OngekiFumenEditor/Parser/DefaultImpl/Nyageki/DefaultNyagekiFumenFormatter.cs @@ -214,7 +214,9 @@ public void ProcessB_PALETTE(OngekiFumen fumen, StreamWriter sb) sb.Write(", "); sb.Write($"Speed[{bpl.Speed}]"); sb.Write(", "); - sb.Write($"PlaceOffset[{bpl.PlaceOffset}]"); + sb.Write($"RandomOffsetRange[{bpl.RandomOffsetRange}]"); + sb.Write(", "); + sb.Write($"PlaceOffset[{bpl.PlaceOffset}]"); sb.Write(", "); sb.Write($"Shooter[{bpl.ShooterValue}]"); sb.WriteLine(); diff --git a/OngekiFumenEditor/Parser/Ogkr/CommandParserImpl/BulletPalleteCommandParser.cs b/OngekiFumenEditor/Parser/Ogkr/CommandParserImpl/BulletPalleteCommandParser.cs index 8c3aef9a..b1748862 100644 --- a/OngekiFumenEditor/Parser/Ogkr/CommandParserImpl/BulletPalleteCommandParser.cs +++ b/OngekiFumenEditor/Parser/Ogkr/CommandParserImpl/BulletPalleteCommandParser.cs @@ -15,8 +15,9 @@ public class BulletPalleteCommandParser : CommandParserBase public override OngekiObjectBase Parse(CommandArgs args, OngekiFumen fumen) { - var dataIntArr = args.GetDataArray(); - var dataStrArr = args.GetDataArray(); + var dataIntArr = args.GetDataArray(); + var dataFloatArr = args.GetDataArray(); + var dataStrArr = args.GetDataArray(); var bpl = new BulletPallete(); bpl.StrID = dataStrArr.ElementAtOrDefault(1); @@ -27,14 +28,14 @@ public override OngekiObjectBase Parse(CommandArgs args, OngekiFumen fumen) "CEN" => Shooter.Center, _ => throw new NotImplementedException(), }; - bpl.PlaceOffset = (int)dataIntArr.ElementAtOrDefault(3); + bpl.PlaceOffset = dataIntArr.ElementAtOrDefault(3); bpl.TargetValue = dataStrArr.ElementAtOrDefault(4)?.ToUpper() switch { "PLR" => Target.Player, "FIX" => Target.FixField, _ => throw new NotImplementedException(), }; - bpl.Speed = dataIntArr.ElementAtOrDefault(5); + bpl.Speed = dataFloatArr.ElementAtOrDefault(5); bpl.SizeValue = dataStrArr.ElementAtOrDefault(6)?.ToUpper() switch { "L" => BulletSize.Large, @@ -46,8 +47,9 @@ public override OngekiObjectBase Parse(CommandArgs args, OngekiFumen fumen) "NDL" => BulletType.Needle, "CIR" or _ => BulletType.Circle, }; + bpl.RandomOffsetRange = dataIntArr.ElementAtOrDefault(8); - return bpl; + return bpl; } } } diff --git a/OngekiFumenEditor/Parser/Ogkr/DefaultOngekiFumenFormatter.cs b/OngekiFumenEditor/Parser/Ogkr/DefaultOngekiFumenFormatter.cs index b6d9b453..4c52f0f5 100644 --- a/OngekiFumenEditor/Parser/Ogkr/DefaultOngekiFumenFormatter.cs +++ b/OngekiFumenEditor/Parser/Ogkr/DefaultOngekiFumenFormatter.cs @@ -209,7 +209,7 @@ public void ProcessB_PALETTE(OngekiFumen fumen, StringBuilder sb) _ => default }; - sb.AppendLine($"{bpl.IDShortName}\t{bpl.StrID}\t{shoot}\t{bpl.PlaceOffset}\t{target}\t{bpl.Speed}\t{size}\t{type}"); + sb.AppendLine($"{bpl.IDShortName}\t{bpl.StrID}\t{shoot}\t{bpl.PlaceOffset}\t{target}\t{bpl.Speed}\t{size}\t{type}\t{bpl.RandomOffsetRange}"); } }