clue plugin: add music clues

Co-authored-by: Hydrox6 <ikada@protonmail.ch>
This commit is contained in:
Adam
2019-04-13 10:34:00 -04:00
parent 90f2b1ad9e
commit 05fdc2877d
5 changed files with 232 additions and 0 deletions

View File

@@ -128,6 +128,7 @@ public class WidgetID
public static final int QUESTLIST_GROUP_ID = 399;
public static final int SKILLS_GROUP_ID = 320;
public static final int QUESTTAB_GROUP_ID = 629;
public static final int MUSIC_GROUP_ID = 239;
static class WorldMap
{
@@ -764,4 +765,10 @@ public class WidgetID
{
static final int QUEST_TAB = 3;
}
static class Music
{
static final int CONTAINER = 0;
static final int LIST = 3;
}
}

View File

@@ -76,6 +76,9 @@ public enum WidgetInfo
EMOTE_WINDOW(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_WINDOW),
EMOTE_CONTAINER(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_CONTAINER),
MUSIC_WINDOW(WidgetID.MUSIC_GROUP_ID, WidgetID.Music.CONTAINER),
MUSIC_TRACK_LIST(WidgetID.MUSIC_GROUP_ID, WidgetID.Music.LIST),
DIARY_QUEST_WIDGET_TITLE(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TITLE),
DIARY_QUEST_WIDGET_TEXT(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TEXT),

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2019, Hydrox6 <ikada@protonmail.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.cluescrolls;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.plugins.cluescrolls.clues.ClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.MusicClue;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
class ClueScrollMusicOverlay extends Overlay
{
private static final Rectangle PADDING = new Rectangle(2, 1, 0, 1);
private final ClueScrollPlugin plugin;
private final Client client;
@Inject
private ClueScrollMusicOverlay(ClueScrollPlugin plugin, Client client)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.plugin = plugin;
this.client = client;
}
@Override
public Dimension render(Graphics2D graphics)
{
ClueScroll clue = plugin.getClue();
if (!(clue instanceof MusicClue))
{
return null;
}
MusicClue musicClue = (MusicClue) clue;
Widget musicContainer = client.getWidget(WidgetInfo.MUSIC_WINDOW);
if (musicContainer == null || musicContainer.isHidden())
{
return null;
}
Widget trackList = client.getWidget(WidgetInfo.MUSIC_TRACK_LIST);
String trackToFind = musicClue.getSong();
Widget found = null;
if (trackList == null)
{
return null;
}
for (Widget track : trackList.getDynamicChildren())
{
if (track.getText().equals(trackToFind))
{
found = track;
break;
}
}
if (found == null)
{
return null;
}
plugin.highlightWidget(graphics, found, trackList, PADDING, null);
return null;
}
}

View File

@@ -85,6 +85,7 @@ import net.runelite.client.plugins.cluescrolls.clues.HotColdClue;
import net.runelite.client.plugins.cluescrolls.clues.LocationClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.LocationsClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.MapClue;
import net.runelite.client.plugins.cluescrolls.clues.MusicClue;
import net.runelite.client.plugins.cluescrolls.clues.NpcClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.ObjectClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.TextClueScroll;
@@ -139,6 +140,9 @@ public class ClueScrollPlugin extends Plugin
@Inject
private ClueScrollEmoteOverlay clueScrollEmoteOverlay;
@Inject
private ClueScrollMusicOverlay clueScrollMusicOverlay;
@Inject
private ClueScrollWorldOverlay clueScrollWorldOverlay;
@@ -173,6 +177,7 @@ public class ClueScrollPlugin extends Plugin
overlayManager.add(clueScrollOverlay);
overlayManager.add(clueScrollEmoteOverlay);
overlayManager.add(clueScrollWorldOverlay);
overlayManager.add(clueScrollMusicOverlay);
}
@Override
@@ -181,6 +186,7 @@ public class ClueScrollPlugin extends Plugin
overlayManager.remove(clueScrollOverlay);
overlayManager.remove(clueScrollEmoteOverlay);
overlayManager.remove(clueScrollWorldOverlay);
overlayManager.remove(clueScrollMusicOverlay);
npcsToMark.clear();
inventoryItems = null;
equippedItems = null;
@@ -469,6 +475,11 @@ public class ClueScrollPlugin extends Plugin
return CipherClue.forText(text);
}
if (text.startsWith("i'd like to hear some music."))
{
return MusicClue.forText(clueScrollText.getText());
}
if (text.contains("degrees") && text.contains("minutes"))
{
return coordinatesToWorldPoint(text);

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2019, Hydrox6 <ikada@protonmail.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.cluescrolls.clues;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.Getter;
import net.runelite.api.NPC;
import net.runelite.api.coords.WorldPoint;
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.components.TitleComponent;
@Getter
public class MusicClue extends ClueScroll implements NpcClueScroll
{
private static final WorldPoint LOCATION = new WorldPoint(2990, 3384, 0);
private static final String CECILIA = "Cecilia";
private static final Pattern SONG_PATTERN = Pattern.compile("<col=ffffff>([A-Za-z !&',.]+)</col>");
private final String song;
private MusicClue(String song)
{
this.song = song;
}
@Override
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
{
panelComponent.getChildren().add(TitleComponent.builder().text("Music Clue").build());
panelComponent.getChildren().add(LineComponent.builder().left("NPC:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left(CECILIA)
.leftColor(TITLED_CONTENT_COLOR)
.build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left("Falador Park")
.leftColor(TITLED_CONTENT_COLOR)
.build());
panelComponent.getChildren().add(LineComponent.builder().left("Song:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left(song)
.leftColor(TITLED_CONTENT_COLOR)
.build());
}
@Override
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
{
if (!LOCATION.isInScene(plugin.getClient()))
{
return;
}
for (NPC npc : plugin.getNpcsToMark())
{
OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET);
}
}
@Override
public String[] getNpcs()
{
return new String[] {CECILIA};
}
public static MusicClue forText(String text)
{
final Matcher m = SONG_PATTERN.matcher(text);
if (m.find())
{
final String song = m.group(1);
return new MusicClue(song);
}
return null;
}
}