sscharter 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d910ec574007b1cb1500a42a871e586666a358e736c211e1191414491f0279e7
4
- data.tar.gz: eb7888975a5b9d4fdaad36bc5ccd165b17b9ac750937f69d9086f9c44d473dc1
3
+ metadata.gz: e26848981238d761f60a4786887aa548f502cd3368ac7eb1f7519ce3de0c45c4
4
+ data.tar.gz: 7cc0a9f86404d13634c0cdd5c693efd70bc25da2f6683b70c8f51c304ea4254e
5
5
  SHA512:
6
- metadata.gz: 06c443975c5f6d858f052623fa32890e7bc5808c0359d566142fe02e7030c267fcb97a4b4a8159ffcd9192308aac76cf3dc70c1e18be84d989ff2f2c35a39b84
7
- data.tar.gz: f59447ecfc433ae851969f1a2f4ffb76e9d63c9bb9a5598d2d06114c5912fcee4a4486071c9495c0b666b5813442eb7350638d0f52c78745278d157b32d938fa
6
+ metadata.gz: 2f63c492ff1d26eeba0b259f1e644fd5c848f1a578624198f085a142242094211d89ab91e2087466f8ee7a74093e311a73ba4d076d427830bbeffad43dbdc153
7
+ data.tar.gz: 6f80c45d548c2ad1509fd0854226343f4da2bca7f407019c517c525244b9d1ba7b0d0890bbf94938e92ecc55728dd500db828003c3668bcca80e6c1bbeca6745
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sscharter (0.2.2)
4
+ sscharter (0.4.0)
5
5
  filewatcher (~> 2.0)
6
6
  launchy (~> 2.5)
7
7
  rubyzip (~> 2.3)
data/lib/sscharter/cli.rb CHANGED
@@ -176,10 +176,11 @@ module Sunniesnow::Charter::CLI
176
176
  port = port.to_i
177
177
  config = self.config
178
178
  server = WEBrick::HTTPServer.new Port: port, DocumentRoot: config[:build_dir]
179
- server.mount_proc "/#{config[:project_name]}.ssc" do |request, response|
180
- response['Content-Type'] = 'application/zip'
179
+ def server.service request, response
180
+ super
181
181
  response['Access-Control-Allow-Origin'] = '*'
182
- response.body = File.read File.join(config[:build_dir], "#{config[:project_name]}.ssc"), binmode: true
182
+ response['Cache-Control'] = 'no-cache'
183
+ response['Content-Type'] = 'application/zip' if request.path.end_with? '.ssc'
183
184
  end
184
185
  url = CGI.escape "http://localhost:#{port}/#{config[:project_name]}.ssc"
185
186
  filewatcher = Filewatcher.new [config[:files_dir], config[:sources_dir], *config[:include]]
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sunniesnow
4
4
  class Charter
5
- VERSION = "0.2.2"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
data/lib/sscharter.rb CHANGED
@@ -312,10 +312,11 @@ class Sunniesnow::Charter
312
312
  @current_offset = nil
313
313
  @current_beat = nil
314
314
  @bpm_changes = nil
315
- @tip_point_mode = :none
316
- @current_tip_point = 0
315
+ @tip_point_mode_stack = [:none]
316
+ @current_tip_point_stack = []
317
+ @tip_point_peak = 0
317
318
  @current_duplicate = 0
318
- @tip_point_start_to_add = nil
319
+ @tip_point_start_to_add_stack = [nil]
319
320
  @groups = [@events]
320
321
  end
321
322
 
@@ -410,7 +411,7 @@ class Sunniesnow::Charter
410
411
  def tip_point_chain *args, preserve_beat: true, **opts, &block
411
412
  tip_point :chain, *args, **opts do
412
413
  group preserve_beat: preserve_beat, &block
413
- end.tap { @current_tip_point += 1 }
414
+ end#.tap { @tip_point_peak += 1 }
414
415
  end
415
416
  alias tp_chain tip_point_chain
416
417
 
@@ -421,6 +422,13 @@ class Sunniesnow::Charter
421
422
  end
422
423
  alias tp_drop tip_point_drop
423
424
 
425
+ def tip_point_none preserve_beat: true, &block
426
+ tip_point :none do
427
+ group preserve_beat: preserve_beat, &block
428
+ end
429
+ end
430
+ alias tp_none tip_point_none
431
+
424
432
  def group preserve_beat: true, &block
425
433
  raise ArgumentError, 'no block given' unless block
426
434
  @groups.push result = []
@@ -439,19 +447,19 @@ class Sunniesnow::Charter
439
447
  result
440
448
  end
441
449
 
442
- def clear_tip_point
443
- TipPointError.ensure @tip_point_mode, :chain, :drop
444
- @tip_point_start_to_add = nil
445
- @tip_point_mode = :none
446
- end
447
-
448
450
  def tip_point mode, *args, **opts, &block
449
- TipPointError.ensure @tip_point_mode, :none
450
- @tip_point_mode = mode
451
- @tip_point_start_to_add = TipPointStart.new *args, **opts
451
+ @tip_point_mode_stack.push mode
452
+ if mode == :none
453
+ @current_tip_point_stack.push nil
454
+ else
455
+ @tip_point_start_to_add_stack.push TipPointStart.new *args, **opts
456
+ @current_tip_point_stack.push @tip_point_peak
457
+ @tip_point_peak += 1
458
+ end
452
459
  result = block.()
453
- @tip_point_start_to_add = nil
454
- @tip_point_mode = :none
460
+ @tip_point_start_to_add_stack.pop
461
+ @tip_point_mode_stack.pop
462
+ @current_tip_point_stack.pop
455
463
  result
456
464
  end
457
465
 
@@ -460,13 +468,14 @@ class Sunniesnow::Charter
460
468
  event = Event.new type, @current_beat, duration_beats, @bpm_changes, **properties
461
469
  @groups.each { _1.push event }
462
470
  return event unless event.tip_pointable?
463
- case @tip_point_mode
471
+ case @tip_point_mode_stack.last
464
472
  when :chain
465
473
  push_tip_point_start event
466
- @tip_point_start_to_add = nil
474
+ @tip_point_start_to_add_stack[-1] = nil
467
475
  when :drop
468
476
  push_tip_point_start event
469
- @current_tip_point += 1
477
+ @current_tip_point_stack[-1] = @tip_point_peak
478
+ @tip_point_peak += 1
470
479
  when :none
471
480
  # pass
472
481
  end
@@ -474,8 +483,8 @@ class Sunniesnow::Charter
474
483
  end
475
484
 
476
485
  def push_tip_point_start start_event
477
- start_event[:tip_point] = @current_tip_point.to_s
478
- tip_point_start = @tip_point_start_to_add&.get_start_placeholder start_event
486
+ start_event[:tip_point] = @current_tip_point_stack.last.to_s
487
+ tip_point_start = @tip_point_start_to_add_stack.last&.get_start_placeholder start_event
479
488
  @groups.each { _1.push tip_point_start } if tip_point_start
480
489
  end
481
490
 
@@ -487,16 +496,17 @@ class Sunniesnow::Charter
487
496
  events.each { transform.apply _1 }
488
497
  end
489
498
 
490
- def duplicate events
499
+ def duplicate events, new_tip_points: true
491
500
  result = []
492
501
  events.each do |event|
502
+ next if event.type == :placeholder && !new_tip_points
493
503
  result.push event = event.dup
494
- if event[:tip_point]
504
+ if event[:tip_point] && new_tip_points
495
505
  event[:tip_point] = "#@current_duplicate #{event[:tip_point]}"
496
506
  end
497
507
  @groups.each { _1.push event }
498
508
  end
499
- @current_duplicate += 1
509
+ @current_duplicate += 1 if new_tip_points
500
510
  result
501
511
  end
502
512
 
@@ -543,11 +553,19 @@ class Sunniesnow::Charter
543
553
  else
544
554
  raise ArgumentError, 'direction must be a symbol or a number'
545
555
  end
546
- event :flick, x: x, y: y, angle: direction, text: text.to_s
556
+ event :flick, x: x.to_f, y: y.to_f, angle: direction, text: text.to_s
547
557
  end
548
558
  alias f flick
549
559
 
550
- def bg_note x, y, duration_beats = 0, text = ''
560
+ def bg_note x, y, duration_beats = 0, text = nil
561
+ if text.nil?
562
+ if duration_beats.is_a? String
563
+ text = duration_beats
564
+ duration_beats = 0
565
+ else
566
+ text = ''
567
+ end
568
+ end
551
569
  if !x.is_a?(Numeric) || !y.is_a?(Numeric) || !duration_beats.is_a?(Numeric)
552
570
  raise ArgumentError, 'x, y, and duration_beats must be numbers'
553
571
  end
data/tutorial/tutorial.md CHANGED
@@ -701,6 +701,13 @@ end
701
701
  transform(notes) { translate 25, 25 }
702
702
  ```
703
703
 
704
+ > Because argument of `rotate` is in radians,
705
+ > you may want to use the Math constant $\pi$.
706
+ > In Ruby, it is `Math::PI`.
707
+ > If you use this constant a lot, you may want to write `include Math`
708
+ > at the beginning of the source codes file so that you can just write `PI`
709
+ > instead of `Math::PI` every time.
710
+
704
711
  ### Navigate among beats
705
712
 
706
713
  You have already learned how to use `beat` to proceed the current beat
@@ -853,33 +860,46 @@ in the call of `tip_point_chain` or `tip_point_drop`.
853
860
  The beat speed may be specified as a float number,
854
861
  and this is the only case where something related to beats is not preferred to be specified as a rational number.
855
862
 
856
- We can categorize the four ways into a table:
863
+ Besides the two methods `tip_point_chain` and `tip_point_drop`,
864
+ there is another method `tip_point_none` (abbreviated as `tp_none`)
865
+ for you to specify that those events in the code block are not connected by tip points.
866
+ This is useful when you nest those methods inside each other.
867
+ Different from `tip_point_chain` and `tip_point_drop`,
868
+ the method `tip_point_none` does not take any arguments
869
+ (besides `preserve_beat`, which will be mentioned later).
870
+
871
+ We can summarize all of them in the following table:
857
872
 
858
873
  <table>
859
874
  <tr>
860
875
  <th>Method</th>
861
876
  <td><code>tip_point_chain</code></td>
862
877
  <td><code>tip_point_drop</code></td>
878
+ <td><code>tip_point_none</code></td>
863
879
  </tr>
864
880
  <tr>
865
881
  <th><code>relative_time</code></th>
866
882
  <td><code>tip_point_chain x=0, y=0, relative_time=0.0, relative: true</code></td>
867
883
  <td><code>tip_point_drop x=0, y=0, relative_time=0.0, relative: true</code></td>
884
+ <td></td>
868
885
  </tr>
869
886
  <tr>
870
887
  <th><code>speed</code></th>
871
888
  <td><code>tip_point_chain x=0, y=0, relative: true, speed:</code></td>
872
889
  <td><code>tip_point_drop x=0, y=0, relative: true, speed:</code></td>
890
+ <td></td>
873
891
  </tr>
874
892
  <tr>
875
893
  <th><code>relative_beat</code></th>
876
894
  <td><code>tip_point_chain x=0, y=0, relative: true, relative_beat:</code></td>
877
895
  <td><code>tip_point_drop x=0, y=0, relative: true, relative_beat:</code></td>
896
+ <td></td>
878
897
  </tr>
879
898
  <tr>
880
899
  <th><code>beat_speed</code></th>
881
900
  <td><code>tip_point_chain x=0, y=0, relative: true, beat_speed:</code></td>
882
901
  <td><code>tip_point_drop x=0, y=0, relative: true, beat_speed:</code></td>
902
+ <td></td>
883
903
  </tr>
884
904
  </table>
885
905
 
@@ -989,11 +1009,21 @@ You may build the level file and play it on Sunniesnow to see what you have done
989
1009
 
990
1010
  ![Second chart](https://i.imgur.com/ksu5sVW.png)
991
1011
 
992
- *Notice*:
993
1012
  When duplicating tip-pointed events,
994
1013
  the duplicated events are not connected by the same tip point as the original events.
995
1014
  However, if two original events are connected by the same tip point,
996
1015
  their duplicates are also connected by the same tip point, too.
1016
+ If you want the duplicated events to be connected by the same tip point as the original events,
1017
+ you can add set the keyword argument `new_tip_points:` to `false` in the call of `duplicate`:
1018
+
1019
+ ```ruby
1020
+ notes = tp_chain 0, 100, speed: 100 do
1021
+ # notes...
1022
+ end
1023
+ transform duplicate notes, new_tip_points: false do
1024
+ # transforms...
1025
+ end
1026
+ ```
997
1027
 
998
1028
  ## Advanced charting techniques
999
1029
 
@@ -1007,7 +1037,7 @@ TODO.
1007
1037
 
1008
1038
  ### Tip points and placeholders
1009
1039
 
1010
- ### Multiple offsets
1040
+ ### Multiple offsets and timing tweaking
1011
1041
 
1012
1042
  ### JSON post-processing
1013
1043
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sscharter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ulysses Zhan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-08 00:00:00.000000000 Z
11
+ date: 2023-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip