clue plugin: add music clues
Co-authored-by: Hydrox6 <ikada@protonmail.ch>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user