|
| 1 | +(* |
| 2 | +# Music |
| 3 | +Music is resposible for the track handling in the Music gametab. |
| 4 | +*) |
| 5 | + |
1 | 6 | {$DEFINE WL_MUSIC_INCLUDED} |
2 | 7 | {$INCLUDE_ONCE WaspLib/osrs.simba} |
3 | 8 |
|
4 | 9 | type |
| 10 | +(* |
| 11 | +## ERSMusicButton |
| 12 | +```pascal |
| 13 | +ERSMusicButton = enum(AREA, MANUAL, RANDOM); |
| 14 | +``` |
| 15 | +Enum representing the music configuration buttons. |
| 16 | +*) |
| 17 | + ERSMusicButton = enum(AREA, MANUAL, RANDOM); |
| 18 | + |
| 19 | +(* |
| 20 | +## TRSMusic |
| 21 | +Main record that interacts with the {ref}`Music` gametab. |
| 22 | +*) |
5 | 23 | TRSMusic = record |
6 | | - Slots: TBoxArray; |
| 24 | + Scroll: TRSScrollBar; |
| 25 | + Buttons: TRSButtonArray; |
| 26 | + end; |
| 27 | + |
| 28 | +(* |
| 29 | +## TRSMusicTrack |
| 30 | +Helper record for {ref}`TRSMusic`. |
| 31 | +*) |
| 32 | + TRSMusicTrack = record |
| 33 | + Name: String; |
| 34 | + Available: Boolean; |
| 35 | + Bounds: TBox; |
7 | 36 | end; |
8 | 37 |
|
| 38 | +(* |
| 39 | +## TRSMusicTrackArray |
| 40 | +Helper type for {ref}`TRSMusic`. |
| 41 | +*) |
| 42 | + TRSMusicTrackArray = array of TRSMusicTrack; |
| 43 | + |
| 44 | +(* |
| 45 | +## TRSMusic.SetupGameTab |
| 46 | +```pascal |
| 47 | +procedure TRSMusic.SetupGameTab(); |
| 48 | +``` |
| 49 | +Interal method used to setup the {ref}`TRSMusic` coordinates. |
| 50 | + |
| 51 | +This is automatically called for you on the {ref}`Music variable`. |
| 52 | +*) |
9 | 53 | procedure TRSMusic.SetupGameTab(); |
10 | 54 | begin |
11 | | - //TODO... |
| 55 | + with GameTab.Bounds do |
| 56 | + begin |
| 57 | + Self.Scroll.Area.X1 := X1 + 5; |
| 58 | + Self.Scroll.Area.Y1 := Y1 + 59; |
| 59 | + Self.Scroll.Area.X2 := X2 - 21; |
| 60 | + Self.Scroll.Area.Y2 := Y2 - 19; |
| 61 | + |
| 62 | + Self.Buttons := TRSButtonArray.Create([[$1D1F81, 0], [$181A6C, 0], [$1A1C74, 0], [$20238D, 0]], TBoxArray.Create([X1+61, Y1+7], 3, 1, 35, 24, [7, 0])); |
| 63 | + end; |
| 64 | + |
| 65 | + Self.Scroll.Setup(); |
| 66 | +end; |
| 67 | + |
| 68 | +(* |
| 69 | +## Music.IsOpen |
| 70 | +```pascal |
| 71 | +function TRSMusic.IsOpen(): Boolean; |
| 72 | +``` |
| 73 | +Returns true if the music gametab is open. |
| 74 | + |
| 75 | +Example: |
| 76 | +```pascal |
| 77 | +WriteLn Music.IsOpen(); |
| 78 | +``` |
| 79 | +*) |
| 80 | +function TRSMusic.IsOpen() : Boolean; |
| 81 | +begin |
| 82 | + Result := GameTabs.IsOpen(ERSGameTab.MUSIC); |
| 83 | +end; |
| 84 | + |
| 85 | +(* |
| 86 | +## Music.Open |
| 87 | +```pascal |
| 88 | +function TRSMusic.Open(): Boolean; |
| 89 | +``` |
| 90 | +Attempts to open the Music gametab. |
| 91 | + |
| 92 | +Example: |
| 93 | +```pascal |
| 94 | +WriteLn Music.Open(); |
| 95 | +``` |
| 96 | +*) |
| 97 | +function TRSMusic.Open() : Boolean; |
| 98 | +begin |
| 99 | + Result := GameTabs.Open(ERSGameTab.MUSIC); |
| 100 | +end; |
| 101 | + |
| 102 | +(* |
| 103 | +## Music.ActiveTrack |
| 104 | +```pascal |
| 105 | +property TRSMusic.ActiveTrack : String; |
| 106 | +``` |
| 107 | +Returns the currently playing track. |
| 108 | + |
| 109 | +Example: |
| 110 | +```pascal |
| 111 | +WriteLn Music.ActiveTrack; |
| 112 | +``` |
| 113 | +*) |
| 114 | +property TRSMusic.ActiveTrack : String; |
| 115 | +begin |
| 116 | + if not Self.Open() then Exit; |
| 117 | + with GameTab.Bounds do |
| 118 | + begin |
| 119 | + Result := OCR.Recognize([X1, Y1 + 35, X2, Y1 + 51], RSFonts.PLAIN_12, [RSFonts.LIGHT_GREEN], 0); |
| 120 | + end; |
| 121 | +end; |
| 122 | + |
| 123 | +(* |
| 124 | +## Music.GetTracks |
| 125 | +```pascal |
| 126 | +function TRSMusic.GetTracks() : TRSMusicTrackArray; |
| 127 | +``` |
| 128 | +Returns the currently visible {ref}`TRSMusicTrackArray`. |
| 129 | + |
| 130 | +Example: |
| 131 | +```pascal |
| 132 | +WriteLn Music.GetTracks(); |
| 133 | +``` |
| 134 | +*) |
| 135 | +function TRSMusic.GetTracks() : TRSMusicTrackArray; |
| 136 | +var |
| 137 | + tpa : TPointArray; |
| 138 | + atpa : T2DPointArray; |
| 139 | + track: TRSMusicTrack; |
| 140 | + weights: TIntegerArray; |
| 141 | +begin |
| 142 | + if not Self.Open() then Exit; |
| 143 | + |
| 144 | + if Target.HasColor(RSFonts.WHITE, 0, 1, Self.Scroll.Area) then |
| 145 | + Mouse.Move(Self.Scroll.Area.NearestEdge(Mouse.Position)); |
| 146 | + |
| 147 | + tpa := Target.FindColor(RSFonts.LIGHT_GREEN, 0, Self.Scroll.Area) + Target.FindColor(RSFonts.RED, 0, Self.Scroll.Area); |
| 148 | + atpa := tpa.Cluster(10, 1.5); |
| 149 | + for tpa in atpa do |
| 150 | + with tpa.Bounds() do |
| 151 | + begin |
| 152 | + track.Name := OCR.Recognize([X1, Y1, X2, Y2], RSFonts.PLAIN_12, [RSFonts.LIGHT_GREEN, RSFonts.RED], 0); |
| 153 | + |
| 154 | + if track.Name = '' then Continue; |
| 155 | + |
| 156 | + track.Available := Target.HasColor(RSFonts.LIGHT_GREEN, 0, 1, [X1, Y1, X2, Y2]); |
| 157 | + track.Bounds := [X1, Y1, X2, Y2]; |
| 158 | + |
| 159 | + weights += Y1; |
| 160 | + Result += track; |
| 161 | + end; |
| 162 | + |
| 163 | + Result.Sort(Weights, True); |
| 164 | +end; |
| 165 | + |
| 166 | +(* |
| 167 | +## Music.FindTrack |
| 168 | +```pascal |
| 169 | +function TRSMusic.FindTrack(trackName: String) : TRSMusicTrack; |
| 170 | +``` |
| 171 | +Returns a {ref}`TRSMusicTrack` if it was found in the playlist. |
| 172 | + |
| 173 | +Example: |
| 174 | +```pascal |
| 175 | +var |
| 176 | + track: TRSMusicTrack; |
| 177 | +begin |
| 178 | + track := Music.FindTrack('Sea Shanty 2'); |
| 179 | + if track <> Default(TRSMusicTrack) then |
| 180 | + WriteLn track.Available; |
| 181 | +end. |
| 182 | +``` |
| 183 | +*) |
| 184 | +function TRSMusic.FindTrack(trackName: String) : TRSMusicTrack; |
| 185 | +var |
| 186 | + track: TRSMusicTrack; |
| 187 | + trackIndex: Integer; |
| 188 | + page: String; |
| 189 | + matchArray: TRegExprMatchArray; |
| 190 | + timeout: TCountDown; |
| 191 | +begin |
| 192 | + if not Self.Open() then Exit; |
| 193 | + |
| 194 | + HTTPClient.Reset(); |
| 195 | + page := HTTPClient.Get('https://oldschool.runescape.wiki/w/Music'); |
| 196 | + matchArray := page.RegExprFindAll('data-music-track-name="(.*?)"'); |
| 197 | + for trackIndex := 0 to High(matchArray) do |
| 198 | + begin |
| 199 | + if matchArray[trackIndex].Groups[0].Match.Equals(trackName, False) then |
| 200 | + break; |
| 201 | + end; |
| 202 | + |
| 203 | + timeout.Start(10 * ONE_SECOND); |
| 204 | + |
| 205 | + Self.Scroll.SetLevel(((trackIndex * 100) div high(matchArray))-1); |
| 206 | + |
| 207 | + repeat |
| 208 | + for track in Self.GetTracks() do |
| 209 | + if track.Name.Equals(trackName, false) then |
| 210 | + Exit(track); |
| 211 | + |
| 212 | + Self.Scroll.Scroll(1, true); |
| 213 | + Biometrics.Sleep(600); |
| 214 | + until timeout.IsFinished; |
| 215 | +end; |
| 216 | + |
| 217 | +(* |
| 218 | +## Music.PlayTrack |
| 219 | +```pascal |
| 220 | +function TRSMusic.PlayTrack(trackName: String; force: Boolean = false) : Boolean; |
| 221 | +``` |
| 222 | +Attempts to play the given track, if the track is already playing it can be clicked again by using the force parameter. |
| 223 | +Returns true if successful. |
| 224 | + |
| 225 | +Example: |
| 226 | +```pascal |
| 227 | +WriteLn Music.PlayTrack('Sea Shanty 2'); |
| 228 | +``` |
| 229 | +*) |
| 230 | +function TRSMusic.PlayTrack(trackName: String; force: Boolean = false) : Boolean; |
| 231 | +var |
| 232 | + track: TRSMusicTrack; |
| 233 | +begin |
| 234 | + if not Self.Open() then Exit; |
| 235 | + if (Self.ActiveTrack.Equals(trackName, false) and not force) then Exit(True); |
| 236 | + |
| 237 | + track := Self.FindTrack(trackName); |
| 238 | + if track = Default(TRSMusicTrack) then Exit; |
| 239 | + if not track.Available then Exit; |
| 240 | + |
| 241 | + Mouse.Click(track.Bounds, EMouseButton.LEFT); |
| 242 | + Result := SleepUntil(Self.ActiveTrack.Equals(trackName, False), 250, 2000); |
12 | 243 | end; |
13 | 244 |
|
| 245 | +(* |
| 246 | +## Music variable |
| 247 | +Global {ref}`TRSMusic` variable. |
| 248 | +*) |
14 | 249 | var |
15 | 250 | Music: TRSMusic; |
0 commit comments