silkedit 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a12669881e8a00f516320116750f2e45aa5e784e10b4cdb68ad7a2b1d5fb1f91
4
- data.tar.gz: 23234270ca141a2f408b1a012d8effb9730e703e2e2444d4c43a2d5d5a77106d
3
+ metadata.gz: 59acadecebfa7ff2b98fbccabf203cc9f03cf092f9358ee0366031aa6b0e0024
4
+ data.tar.gz: c8ecb69055f19e1f7be924dec8b5d51cc42b9c8d0e4edb0b82a8879cb1aa2dc5
5
5
  SHA512:
6
- metadata.gz: f66c14e57b5fe04d97bec8bdc2d540e6a95fb29be890007e923cf50ec080118f3aa263e29bc476c8b6e1dcb66d862c2b4a0b642552de93ba80c1ceec63907724
7
- data.tar.gz: a5c2d93939d57933ec9444516b21cf00c62b9f8df2426eb02af671860096bf87b4d2e05c5d0a7ebfd25c9af7b0c6b3aa3f89effdf5547f3326360c3a84d645ef
6
+ metadata.gz: 88a7be67351215bc3936d245a7b77a33b86f6f7bbaa119508b972b625a3133f1f81518eb811b7e54f0be873f6470e059c888835fbfa503e02432099741b47b41
7
+ data.tar.gz: 46b28d7d3f421f8068a0b7ab3bc92da0df83956824998d5b5150e1ddbf3d94d14f0ca270fd379a04ec45f60b90252d0945a481ffe6e65a0c93df76e7dbf123cf
@@ -2,18 +2,67 @@ Rbcli.command 'cheat' do
2
2
  description 'Applies one or more cheats to the selected savefile'
3
3
  usage '<cheat1> <cheat2> <cheat3>...'
4
4
  parameter :list, 'List all cheats', type: :bool, default: false
5
+ # parameter :force, "Force application of a cheat even when requirements aren't met. Additional changes may be made to your savegave.", type: :bool, default: false
5
6
  action do |opts, params, args, config, env|
6
7
  s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
7
8
  s.load_from_dat
8
9
  c = Silkedit::Cheat::Engine.new(s.data)
9
- selected_cheats = args.map { |arg| arg.downcase }.select { |cht| c.cheat_exists?(cht) }
10
- if params[:list] || selected_cheats.empty?
11
- Rbcli.log.info "Cheats: \n" + c.list_cheats.map(&:to_s).join("\n")
12
- else
13
- selected_cheats.each { |cht| c.apply_cheat(cht) }
14
- s.direct_backup
15
- s.save_to_dat
16
- Rbcli.log.info "applied cheats: #{selected_cheats.join(', ')}"
10
+
11
+ display_simple_list = lambda do |list, cols|
12
+ max_length = list.map(&:length).max
13
+ display_set = []
14
+ rows = (list.length / cols.to_f).ceil
15
+ row_idx = 0
16
+ max_rows = rows - 1
17
+ list.length.times do |i|
18
+ display_set[row_idx] ||= []
19
+ display_set[row_idx] << list[i]
20
+ row_idx += 1
21
+ row_idx = 0 if row_idx > max_rows
22
+ end
23
+ display_set.map { |row| row.map { |z| z.ljust(max_length) }.join(' ') }.join("\n")
17
24
  end
25
+
26
+ if args.empty? || params[:list]
27
+ Rbcli.log.info 'Cheats:'
28
+ Rbcli.log.info display_simple_list.call(c.list_cheats, 5)
29
+ Rbcli.exit(0)
30
+ end
31
+
32
+ changes = args.map do |cht|
33
+ cht = cht.downcase
34
+ status = c.apply_cheat(cht)
35
+ case status
36
+ when :no_cheat
37
+ Rbcli.log.warn "Could not apply cheat #{cht}: Cheat does not exist"
38
+ Rbcli.log.info 'Did you mean one of these?'
39
+ possible_cheats = c.list_cheats.select { |cheat| cheat.include?(args.first) }
40
+ Rbcli.log.info display_simple_list.call(possible_cheats, 5)
41
+ nil
42
+ when :failed_act_check
43
+ Rbcli.log.warn "Could not apply cheat #{cht.colorize(:red)}: The player is in the wrong act. Use --(f)orce to override."
44
+ nil
45
+ when :failed_soft_reqs
46
+ Rbcli.log.warn "Could not apply cheat #{cht.colorize(:red)}: Soft requirements not met. Use --(f)orce to apply the required changes."
47
+ nil
48
+ when :failed_hard_reqs
49
+ Rbcli.log.error "Could not apply cheat #{cht.colorize(:red)}: Hard requirements not met. Applying the cheat would cause in-game errors."
50
+ nil
51
+ when :success
52
+ Rbcli.log.info " Success!".colorize(:green)
53
+ cht
54
+ else
55
+ raise "Unknown status: #{status}"
56
+ end
57
+ end.reject(&:nil?)
58
+
59
+ if changes.empty?
60
+ Rbcli.log.info ''
61
+ Rbcli.log.info 'No cheats applied'
62
+ Rbcli.exit(0)
63
+ end
64
+
65
+ s.direct_backup
66
+ s.save_to_dat
18
67
  end
19
68
  end
@@ -1,25 +1,26 @@
1
1
  Rbcli.command 'zone' do
2
2
  description 'Zones the character to a different respawn point'
3
3
  usage '<zone> (--(f)orce)'
4
- parameter :force, 'Force select a spawn point even when requirements are not met. Changes may be made to your savegave.', type: :bool, default: false
5
4
  parameter :list, 'Display the full list of zones to select from', type: :bool, default: false
5
+ parameter :force, 'Force select a spawn point even when requirements are not met. Changes may be made to your savegave.', type: :bool, default: false
6
6
  action do |opts, params, args, config, env|
7
7
  s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
8
8
  s.load_from_dat
9
9
  c = Silkedit::Cheat::Engine.new(s.data)
10
10
 
11
- display_simple_zone_list = lambda do |list, cols|
11
+ display_simple_list = lambda do |list, cols|
12
+ max_length = list.map(&:length).max
12
13
  display_set = []
13
- rows = (c.list_shortcuts.length / cols.to_f).ceil
14
+ rows = (list.length / cols.to_f).ceil
14
15
  row_idx = 0
15
16
  max_rows = rows - 1
16
- c.list_shortcuts.length.times do |i|
17
+ list.length.times do |i|
17
18
  display_set[row_idx] ||= []
18
- display_set[row_idx] << c.list_shortcuts.keys[i]
19
+ display_set[row_idx] << list[i]
19
20
  row_idx += 1
20
21
  row_idx = 0 if row_idx > max_rows
21
22
  end
22
- display_set.map { |row| row.map { |z| z.rjust(15) }.join(' ') }.join("\n")
23
+ display_set.map { |row| row.map { |z| z.ljust(max_length) }.join(' ') }.join("\n")
23
24
  end
24
25
 
25
26
  display_detailed_zone_list = lambda do |list|
@@ -33,7 +34,7 @@ Rbcli.command 'zone' do
33
34
 
34
35
  if args.empty? || params[:list]
35
36
  Rbcli.log.info 'Shortcuts:'
36
- Rbcli.log.info display_simple_zone_list.call(c.list_shortcuts, 5)
37
+ Rbcli.log.info display_simple_list.call(c.list_shortcuts.keys, 5)
37
38
  end
38
39
 
39
40
  if params[:list]
@@ -47,20 +48,20 @@ Rbcli.command 'zone' do
47
48
  status = c.zone_to(args.first, force_soft_reqs: params[:force], enforce_min_act: !params[:force])
48
49
  case status
49
50
  when :no_zone
50
- Rbcli.log.info "Could not zone to #{args.first}: Specified spawn point does not exist"
51
+ Rbcli.log.warn "Could not zone to #{args.first}: Specified spawn point does not exist"
51
52
  Rbcli.log.info 'Did you mean one of these?'
52
53
  possible_zones = c.list_zones.select { |zone| zone[:slug].include?(args.first) || !zone[:shortcut].nil? && zone[:shortcut].include?(args.first) }
53
- Rbcli.log.info display_detailed_zone_list.call(possible_zones)
54
+ Rbcli.log.info display_detailed_zone_list.call(possible_zones, 5)
54
55
  when :failed_act_check
55
- Rbcli.log.warn "Could not zone to #{args.first}: The player is in the wrong act. Use --(f)orce to override."
56
+ Rbcli.log.warn "Could not zone to #{args.first.colorize(:red)}: The player is in the wrong act. Use --(f)orce to override."
56
57
  when :failed_soft_reqs
57
- Rbcli.log.warn "Could not zone to #{args.first}: Soft requirements not met. Use --(f)orce to apply the required changes."
58
+ Rbcli.log.warn "Could not zone to #{args.first.colorize(:red)}: Soft requirements not met. Use --(f)orce to apply the required changes."
58
59
  when :failed_hard_reqs
59
- Rbcli.log.error "Could not zone to #{args.first}: Hard requirements not met. Zoning here would cause errors."
60
+ Rbcli.log.error "Could not zone to #{args.first.colorize(:red)}: Hard requirements not met. Zoning here would cause in-game errors."
60
61
  when :success
61
62
  s.direct_backup
62
63
  s.save_to_dat
63
- Rbcli.log.info "Zoned to #{args.first}"
64
+ Rbcli.log.info "Zoned to #{args.first.colorize(:green)}"
64
65
  else
65
66
  raise "Unknown status: #{status}"
66
67
  end
@@ -8,9 +8,8 @@ module Silkedit::Cheat
8
8
  end
9
9
 
10
10
  def apply_cheat(cheat, *args)
11
- return false unless cheat_exists?(cheat.to_s)
11
+ return :no_cheat unless cheat_exists?(cheat.to_s)
12
12
  self.send(cheat.to_sym, *args)
13
- true
14
13
  end
15
14
 
16
15
  def apply_cheats(cheats)
@@ -31,7 +31,7 @@ module Silkedit::Cheat
31
31
  merge_hash(data[k], cheat[k])
32
32
  elsif should_merge_arrays && cheat[k].is_a?(Array) && data[k].is_a?(Array)
33
33
  if cheat[k][0].is_a?(Hash)
34
- merge_arrays_by_hash_keys(data[k], cheat[k])
34
+ data[k] = merge_arrays_by_hash_keys(data[k], cheat[k])
35
35
  else
36
36
  data[k].merge!(cheat[k])
37
37
  data[k].uniq!
@@ -44,7 +44,11 @@ module Silkedit::Cheat
44
44
  end
45
45
 
46
46
  def self.merge_arrays_by_hash_keys(data, cheat)
47
- return nil unless data.is_a?(Array) && cheat.is_a?(Array) && data.first.is_a?(Hash)
47
+ return data unless data.is_a?(Array) && cheat.is_a?(Array) && cheat.first.is_a?(Hash)
48
+ if data.empty?
49
+ data = cheat
50
+ return data
51
+ end
48
52
  # First determine the primary key(s) for the object
49
53
  pkeys = []
50
54
  [%w[Name], %w[sceneData ID]].each do |pkey_arr|
@@ -58,7 +62,7 @@ module Silkedit::Cheat
58
62
  data << c
59
63
  end
60
64
  end
61
- true
65
+ data
62
66
  end
63
67
 
64
68
  def self.verify_hash(data, reqs)
@@ -33,7 +33,8 @@ module Silkedit::Cheat
33
33
  end
34
34
 
35
35
  def max_everything
36
- %w[
36
+ backup_data = @data.dup
37
+ result = %w[
37
38
  max_health
38
39
  max_silk
39
40
  max_weapon
@@ -48,12 +49,19 @@ module Silkedit::Cheat
48
49
  give_consumables
49
50
  max_rosaries
50
51
  max_shards
51
- ].each { |cht| self.send(cht.to_sym) }
52
+ ].map { |cht| self.send(cht.to_sym) }
53
+ if result.all?(:success)
54
+ :success
55
+ else
56
+ @data = backup_data
57
+ result.reject { |r| r == :success }.first
58
+ end
52
59
  end
53
60
 
54
61
  def max_shards
55
62
  Rbcli.log.info 'Applying cheat max_shards', 'CHEATS'
56
63
  @data['playerData']['ShellShards'] = 400 + (@data['playerData']['ToolPouchUpgrades'] || 0) * 100
64
+ :success
57
65
  end
58
66
 
59
67
  def all_crest_unlocks
@@ -68,11 +76,13 @@ module Silkedit::Cheat
68
76
  end
69
77
  crest['Data']['Slots'].each { |slot| slot['IsUnlocked'] = true }
70
78
  end
79
+ :success
71
80
  end
72
81
 
73
82
  def toggle_map_reveal
74
83
  @data['playerData']['mapAllRooms'] = !@data['playerData']['mapAllRooms']
75
84
  Rbcli.log.info "Full map reveal is #{@data['playerData']['mapAllRooms'] ? 'enabled' : 'disabled'}", 'CHEATS'
85
+ :success
76
86
  end
77
87
 
78
88
  def toggle_flea_reveal
@@ -80,6 +90,7 @@ module Silkedit::Cheat
80
90
  is_enabled = flea_keys.all? { |k| @data['playerData'][k] }
81
91
  flea_keys.each { |k| @data[k] = !is_enabled }
82
92
  Rbcli.log.info "Flea locations are #{is_enabled ? 'hidden' : 'revealed'} on map", 'CHEATS'
93
+ :success
83
94
  end
84
95
 
85
96
  def toggle_cloakless
@@ -110,12 +121,21 @@ module Silkedit::Cheat
110
121
  # @data['playerData']['slab_cloak_battle_completed'] = true
111
122
  @data['playerData']['IsSilkSpoolBroken'] = false
112
123
  end
124
+ :success
113
125
  end
114
126
 
115
127
  def toggle_permadeath_mode
116
128
  toggle = @data['playerData']['permadeathMode'] == 0
117
129
  Rbcli.log.info "Toggling permadeath mode #{toggle ? 'ON' : 'OFF'}", 'CHEATS'
118
130
  @data['playerData']['permadeathMode'] = toggle ? 1 : 0
131
+ :success
132
+ end
133
+
134
+ def toggle_fly_mode
135
+ toggle = @data['playerData']['infiniteAirJump'] == false
136
+ Rbcli.log.info "Toggling fly mode #{toggle ? 'ON' : 'OFF'}", 'CHEATS'
137
+ @data['playerData']['infiniteAirJump'] = toggle ? true : false
138
+ :success
119
139
  end
120
140
  end
121
141
  end
@@ -25,7 +25,7 @@ module Silkedit::Cheat
25
25
  zonelist = Silkedit::Cheat::SilksongZoner.module_eval { @zonelist }
26
26
  shortcuts = Silkedit::Cheat::SilksongZoner.module_eval { @shortcuts }
27
27
  Rbcli.log.info "Zoning to #{zone}", 'ZONER'
28
- return self.zone_to(shortcuts[zone]) if shortcuts.key?(zone)
28
+ return self.zone_to(shortcuts[zone], force_soft_reqs: force_soft_reqs, enforce_min_act: enforce_min_act) if shortcuts.key?(zone)
29
29
  return :no_zone unless zonelist.find { |z| z['slug'] == zone }
30
30
  region, target = zone.split('.')
31
31
  Silkedit::Cheat.merge_cheat(
@@ -27,6 +27,13 @@ cheats:
27
27
  playerData:
28
28
  ToolPouchUpgrades: 4
29
29
  ToolKitUpgrades: 4
30
+ Collectables:
31
+ savedData:
32
+ - Name: Tool Pouch&Kit Inv
33
+ Data:
34
+ Amount: 0
35
+ IsSeenMask: 4
36
+ AmountWhileHidden: 0
30
37
  max_liquids:
31
38
  data:
32
39
  playerData:
@@ -63,6 +70,13 @@ cheats:
63
70
  HasSeenNeedolinDown: true
64
71
  HasSeenHarpoon: true
65
72
  UnlockedFastTravelTeleport: true
73
+ Collectables:
74
+ savedData:
75
+ - Name: Dresses
76
+ Data:
77
+ Amount: 0
78
+ IsSeenMask: 8
79
+ AmountWhileHidden: 0
66
80
  all_crests:
67
81
  data:
68
82
  playerData:
@@ -132,7 +146,6 @@ cheats:
132
146
  playerData:
133
147
  UnlockedFastTravel: true
134
148
  FastTravelNPCLocation: 1
135
- UnlockedFastTravelTeleport: true
136
149
  UnlockedDocksStation: true
137
150
  UnlockedBoneforestEastStation: true
138
151
  UnlockedGreymoorStation: true
@@ -278,6 +291,13 @@ cheats:
278
291
  hasMarker_c: true
279
292
  hasMarker_d: true
280
293
  hasMarker_e: true
294
+ Collectables:
295
+ savedData:
296
+ - Name: Quill
297
+ Data:
298
+ Amount: 1
299
+ IsSeenMask: 255
300
+ AmountWhileHidden: 0
281
301
  all_spells:
282
302
  data:
283
303
  playerData:
@@ -768,85 +788,78 @@ cheats:
768
788
  - Name: Plasmium Gland
769
789
  Data:
770
790
  Amount: 1
771
- IsSeenMask: 0
791
+ IsSeenMask: 1
772
792
  AmountWhileHidden: 0
773
- quill_none:
793
+ ability_dash:
774
794
  data:
775
795
  playerData:
776
- hasQuill: false
777
- QuillState: 0
778
- sceneData:
779
- persistentBools:
780
- serializedList:
781
- - SceneName: Library_13b
782
- ID: Collectable Item Pickup - Quill Red
783
- Value: false
784
- Mutator: 0
785
- - SceneName: Library_13b
786
- ID: Collectable Item Pickup - Quill Purple
787
- Value: false
788
- Mutator: 0
789
- quill_white:
796
+ hasDash: true
797
+ HasSeenDash: true
798
+ ability_doublejump:
790
799
  data:
791
800
  playerData:
792
- hasQuill: true
793
- QuillState: 1
794
- sceneData:
795
- persistentBools:
796
- serializedList:
797
- - SceneName: Library_13b
798
- ID: Collectable Item Pickup - Quill Red
799
- Value: false
800
- Mutator: 0
801
- - SceneName: Library_13b
802
- ID: Collectable Item Pickup - Quill Purple
803
- Value: false
804
- Mutator: 0
805
- quill_red:
801
+ hasDoubleJump: true
802
+ Collectables:
803
+ savedData:
804
+ - Name: Dresses
805
+ Data:
806
+ Amount: 0
807
+ IsSeenMask: 8
808
+ AmountWhileHidden: 0
809
+ ability_drift:
806
810
  data:
807
811
  playerData:
808
- hasQuill: true
809
- QuillState: 2
810
- sceneData:
811
- persistentBools:
812
- serializedList:
813
- - SceneName: Library_13b
814
- ID: Collectable Item Pickup - Quill Red
815
- Value: true
816
- Mutator: 0
817
- - SceneName: Library_13b
818
- ID: Collectable Item Pickup - Quill Purple
819
- Value: false
820
- Mutator: 0
821
- quill_purple:
812
+ hasBrolly: true
813
+ Collectables:
814
+ savedData:
815
+ - Name: Dresses
816
+ Data:
817
+ Amount: 0
818
+ IsSeenMask: 8
819
+ AmountWhileHidden: 0
820
+ ability_walljump:
822
821
  data:
823
822
  playerData:
824
- hasQuill: true
825
- QuillState: 3
826
- sceneData:
827
- persistentBools:
828
- serializedList:
829
- - SceneName: Library_13b
830
- ID: Collectable Item Pickup - Quill Red
831
- Value: false
832
- Mutator: 0
833
- - SceneName: Library_13b
834
- ID: Collectable Item Pickup - Quill Purple
835
- Value: true
836
- Mutator: 0
837
- easy_dice_game_win:
823
+ hasWalljump: true
824
+ HasSeenWalljump: true
825
+ ability_needolin:
838
826
  data:
839
827
  playerData:
840
- dicePilgrimBank: 0
841
- easy_flea_games_win:
828
+ hasNeedolin: true
829
+ HasSeenNeedolin: true
830
+ ability_needolin_up:
842
831
  data:
843
832
  playerData:
844
- fleaGames_juggling_played: true
845
- fleaGames_juggling_highscore: 56
846
- fleaGames_bouncing_played: true
847
- fleaGames_bouncing_highscore: 69
848
- fleaGames_dodging_played: true
849
- fleaGames_dodging_highscore: 96
833
+ hasNeedolinMemoryPowerup: true
834
+ HasSeenNeedolinUp: true
835
+ ability_needolin_down:
836
+ data:
837
+ playerData:
838
+ UnlockedFastTravelTeleport: true
839
+ HasSeenNeedolinDown: true
840
+ ability_harpoon:
841
+ data:
842
+ playerData:
843
+ hasHarpoonDash: true
844
+ HasSeenHarpoon: true
845
+ ability_charge_weapon:
846
+ data:
847
+ playerData:
848
+ hasChargeSlash: true
849
+ ability_silkspecial:
850
+ data:
851
+ playerData:
852
+ hasSilkSpecial: true
853
+ HasSeenSilkSpecial: true
854
+ ability_superjump:
855
+ data:
856
+ playerData:
857
+ hasSuperJump: true
858
+ HasSeenSuperJump: true
859
+ ability_teleport:
860
+ data:
861
+ playerData:
862
+ UnlockedFastTravelTeleport: true
850
863
  complete_mushroom_quest:
851
864
  data:
852
865
  playerData:
@@ -866,21 +879,19 @@ cheats:
866
879
  CompletedCount: 0
867
880
  IsCompleted: true
868
881
  WasEverCompleted: false
869
- unlock_terminus_door:
882
+ easy_dice_game_win:
870
883
  data:
871
884
  playerData:
872
- laceTowerDoorOpened: true
873
- sceneData:
874
- persistentBools:
875
- serializedList:
876
- - SceneName: Tube_Hub
877
- ID: Understore Lever
878
- Value: true
879
- Mutator: 0
880
- - SceneName: Tube_Hub
881
- ID: cradle_pipe_trapdoor
882
- Value: true
883
- Mutator: 0
885
+ dicePilgrimBank: 0
886
+ easy_flea_games_win:
887
+ data:
888
+ playerData:
889
+ fleaGames_juggling_played: true
890
+ fleaGames_juggling_highscore: 56
891
+ fleaGames_bouncing_played: true
892
+ fleaGames_bouncing_highscore: 69
893
+ fleaGames_dodging_played: true
894
+ fleaGames_dodging_highscore: 96
884
895
  give_consumables:
885
896
  data:
886
897
  playerData:
@@ -947,6 +958,150 @@ cheats:
947
958
  data:
948
959
  playerData:
949
960
  ConstructedFarsight: true
961
+ quill_none:
962
+ data:
963
+ playerData:
964
+ hasQuill: false
965
+ QuillState: 0
966
+ sceneData:
967
+ persistentBools:
968
+ serializedList:
969
+ - SceneName: Library_13b
970
+ ID: Collectable Item Pickup - Quill Red
971
+ Value: false
972
+ Mutator: 0
973
+ - SceneName: Library_13b
974
+ ID: Collectable Item Pickup - Quill Purple
975
+ Value: false
976
+ Mutator: 0
977
+ quill_white:
978
+ data:
979
+ playerData:
980
+ hasQuill: true
981
+ QuillState: 1
982
+ Collectables:
983
+ savedData:
984
+ - Name: Quill
985
+ Data:
986
+ Amount: 1
987
+ IsSeenMask: 16
988
+ AmountWhileHidden: 0
989
+ sceneData:
990
+ persistentBools:
991
+ serializedList:
992
+ - SceneName: Library_13b
993
+ ID: Collectable Item Pickup - Quill Red
994
+ Value: false
995
+ Mutator: 0
996
+ - SceneName: Library_13b
997
+ ID: Collectable Item Pickup - Quill Purple
998
+ Value: false
999
+ Mutator: 0
1000
+ quill_red:
1001
+ data:
1002
+ playerData:
1003
+ hasQuill: true
1004
+ QuillState: 2
1005
+ Collectables:
1006
+ savedData:
1007
+ - Name: Quill
1008
+ Data:
1009
+ Amount: 1
1010
+ IsSeenMask: 16
1011
+ AmountWhileHidden: 0
1012
+ sceneData:
1013
+ persistentBools:
1014
+ serializedList:
1015
+ - SceneName: Library_13b
1016
+ ID: Collectable Item Pickup - Quill Red
1017
+ Value: true
1018
+ Mutator: 0
1019
+ - SceneName: Library_13b
1020
+ ID: Collectable Item Pickup - Quill Purple
1021
+ Value: false
1022
+ Mutator: 0
1023
+ quill_purple:
1024
+ data:
1025
+ playerData:
1026
+ hasQuill: true
1027
+ QuillState: 3
1028
+ Collectables:
1029
+ savedData:
1030
+ - Name: Quill
1031
+ Data:
1032
+ Amount: 1
1033
+ IsSeenMask: 72
1034
+ AmountWhileHidden: 0
1035
+ sceneData:
1036
+ persistentBools:
1037
+ serializedList:
1038
+ - SceneName: Library_13b
1039
+ ID: Collectable Item Pickup - Quill Red
1040
+ Value: false
1041
+ Mutator: 0
1042
+ - SceneName: Library_13b
1043
+ ID: Collectable Item Pickup - Quill Purple
1044
+ Value: true
1045
+ Mutator: 0
1046
+ silk_overdrive:
1047
+ data:
1048
+ playerData:
1049
+ silk: 27
1050
+ silkMax: 27
1051
+ silkRegenMax: 27
1052
+ HasSeenSilkHearts: true
1053
+ IsSilkSpoolBroken: false
1054
+ unlock_terminus_door:
1055
+ data:
1056
+ playerData:
1057
+ laceTowerDoorOpened: true
1058
+ sceneData:
1059
+ persistentBools:
1060
+ serializedList:
1061
+ - SceneName: Tube_Hub
1062
+ ID: Understore Lever
1063
+ Value: true
1064
+ Mutator: 0
1065
+ - SceneName: Tube_Hub
1066
+ ID: cradle_pipe_trapdoor
1067
+ Value: true
1068
+ Mutator: 0
1069
+ unlock_all_bellshrines:
1070
+ data:
1071
+ playerData:
1072
+ bellShrineBoneForest: true
1073
+ bellShrineGreymoor: true
1074
+ bellShrineShellwood: true
1075
+ bellShrineBellhart: true
1076
+ bellShrineWilds: true
1077
+ bellShrineEnclave: true
1078
+ sceneData:
1079
+ persistentInts:
1080
+ serializedList:
1081
+ - SceneName: Bellshrine
1082
+ ID: Bellshrine Sequence
1083
+ Value: 3
1084
+ Mutator: 0
1085
+ - SceneName: Bellshrine_02
1086
+ ID: Bellshrine Sequence
1087
+ Value: 3
1088
+ Mutator: 0
1089
+ - SceneName: Bellshrine_03
1090
+ ID: Bellshrine Sequence
1091
+ Value: 3
1092
+ Mutator: 0
1093
+ - SceneName: Belltown_Shrine
1094
+ ID: Bellshrine Sequence Bellhart
1095
+ Value: 3
1096
+ Mutator: 0
1097
+ - SceneName: Bellshrine_05
1098
+ ID: Bellshrine Sequence
1099
+ Value: 3
1100
+ Mutator: 0
1101
+ - SceneName: Bellshrine_Enclave
1102
+ ID: Bellshrine Sequence
1103
+ Value: 3
1104
+ Mutator: 0
950
1105
  reference:
951
1106
  full_crests:
952
1107
  playerData:
@@ -572,6 +572,19 @@ farfields:
572
572
  soft_reqs: {}
573
573
  hard_reqs: {}
574
574
  min_act: 1
575
+ soprano_spawn:
576
+ data:
577
+ playerData:
578
+ atBench: false
579
+ respawnScene: Ant_Queen
580
+ mapZone: 16
581
+ extraRestZone: 0
582
+ respawnMarkerName: Death Respawn Marker
583
+ respawnType: 0
584
+ hazardRespawnFacing: 0
585
+ soft_reqs: {}
586
+ hard_reqs: {}
587
+ min_act: 2
575
588
  sprintmaster:
576
589
  data:
577
590
  playerData:
@@ -890,8 +903,8 @@ marrow:
890
903
  respawnMarkerName: Silk Heart Memory Respawn Marker
891
904
  respawnType: 0
892
905
  hazardRespawnFacing: 0
893
- soft_reqs: { }
894
- hard_reqs: { }
906
+ soft_reqs: {}
907
+ hard_reqs: {}
895
908
  min_act: 1
896
909
  entrance:
897
910
  data:
@@ -1033,6 +1046,19 @@ mossgrove:
1033
1046
  soft_reqs: {}
1034
1047
  hard_reqs: {}
1035
1048
  min_act: 3
1049
+ church_spawn:
1050
+ data:
1051
+ playerData:
1052
+ atBench: false
1053
+ respawnScene: Bonetown
1054
+ mapZone: 18
1055
+ extraRestZone: 0
1056
+ respawnMarkerName: Death Respawn Marker Church
1057
+ respawnType: 0
1058
+ hazardRespawnFacing: 2
1059
+ soft_reqs: {}
1060
+ hard_reqs: {}
1061
+ min_act: 1
1036
1062
  druid:
1037
1063
  data:
1038
1064
  playerData:
@@ -7,49 +7,50 @@ module Silkedit::Savegame
7
7
 
8
8
  diff = nil
9
9
 
10
- if old.is_a?(Hash)
10
+ if old.is_a?(Hash) || new.is_a?(Hash)
11
11
  diff = {}
12
12
  (old.keys + new.keys).uniq.each do |k|
13
13
  itemdiff = mkdiff(old[k], new[k])
14
14
  diff[k] = itemdiff unless itemdiff.nil? || itemdiff.empty?
15
15
  end
16
- elsif old.is_a?(Array)
16
+ elsif old.is_a?(Array) || new.is_a?(Array)
17
17
  diff = []
18
- if old.first.is_a?(Hash)
19
- if old.first.key?('Name')
20
- keycomps = %w[Name]
21
- elsif old.first.key?('SceneName') && old.first.key?('ID')
22
- keycomps = %w[SceneName ID]
23
- elsif old.first.key?('SceneName') && old.first.key?('EventType')
24
- keycomps = %w[SceneName EventType]
25
- else
26
- keycomps = nil
27
- end
28
- if keycomps.nil?
29
- diff = { old: old.reject { |e| new.include?(e) }, new: new.reject { |e| old.include?(e) } }
30
- else
31
- old.each do |o|
32
- n = new.find { |e| keycomps.map { |k| e[k] == o[k] }.reduce { |a, b| a && b } }
33
- itemdiff = mkdiff(
34
- o.reject { |k, _v| keycomps.include?(k) },
35
- n.nil? ? nil : n.reject { |k, _v| keycomps.include?(k) }
36
- )
37
- next if itemdiff.empty?
38
- newobj = {}
39
- keycomps.each { |k| newobj[k] = o[k] }
40
- diff.append(newobj.merge(itemdiff))
41
- end
42
- new.each do |n|
43
- o = old.find { |e| keycomps.map { |k| e[k] == n[k] }.reduce { |a, b| a && b } }
44
- next unless o.nil?
45
- itemdiff = mkdiff(
46
- nil,
47
- n.reject { |k, _v| keycomps.include?(k) }
48
- )
49
- newobj = {}
50
- keycomps.each { |k| newobj[k] = n[k] }
51
- diff.append(newobj.merge(itemdiff))
18
+ if (old.first.is_a?(Hash) && old.first.key?('Name')) ||
19
+ (new.first.is_a?(Hash) && new.first.key?('Name'))
20
+ keycomps = %w[Name]
21
+ elsif (old.first.is_a?(Hash) && old.first.key?('SceneName') && old.first.key?('ID')) ||
22
+ (new.first.is_a?(Hash) && new.first.key?('SceneName') && new.first.key?('ID'))
23
+ keycomps = %w[SceneName ID]
24
+ elsif (old.first.is_a?(Hash) && old.first.key?('SceneName') && old.first.key?('EventType')) ||
25
+ (new.first.is_a?(Hash) && new.first.key?('SceneName') && new.first.key?('EventType'))
26
+ keycomps = %w[SceneName EventType]
27
+ else
28
+ keycomps = nil
29
+ end
30
+ if keycomps.nil?
31
+ diff = { old: old.reject { |e| new.include?(e) }, new: new.reject { |e| old.include?(e) } }
32
+ diff = nil if diff[:old].empty? && diff[:new].empty?
33
+ else
34
+ old.each do |o|
35
+ n = new.find { |e| keycomps.map { |k| e[k] == o[k] }.reduce { |a, b| a && b } }
36
+ if n.nil?
37
+ diff.append({new: n, old: o})
38
+ next
52
39
  end
40
+ itemdiff = mkdiff(
41
+ o.reject { |k, _v| keycomps.include?(k) },
42
+ n.nil? ? nil : n.reject { |k, _v| keycomps.include?(k) }
43
+ )
44
+ next if itemdiff.empty?
45
+ newobj = {}
46
+ keycomps.each { |k| newobj[k] = o[k] }
47
+ diff.append(newobj.merge(itemdiff))
48
+ end
49
+ new.each do |n|
50
+ o = old.find { |e| keycomps.map { |k| e[k] == n[k] }.reduce { |a, b| a && b } }
51
+ next unless o.nil?
52
+ diff.append({new: n, old: o})
53
+ next
53
54
  end
54
55
  end
55
56
  elsif old != new
@@ -71,7 +72,7 @@ module Silkedit::Savegame
71
72
  if line[i] == '-' && blank_leadup
72
73
  colored_string += line[i].colorize(:yellow)
73
74
  i += 1
74
- elsif line[i] == ':' && blank_leadup
75
+ elsif line[i] == ':' && (blank_leadup || line[0..i-1].sub('-', '').chars.map { |c| c == ' ' }.all?)
75
76
  j = i + line[i+1..-1].index(':')
76
77
  colored_string += line[i..j].colorize(:magenta)
77
78
  i += j - i + 1
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Silkedit
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: silkedit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Khoury