This is something i wrote a while ago, sold it to 3 ppl and apparently one of them started selling it to other ppl for $100(and some1 actually bought it lol) so i might as well just release it
You can also give each segment it's own color(actually did that myself but ended up removing it later)
Code:
import java.util.concurrent.ThreadLocalRandom;
/**
* @Author Suic
*/
public class WheelOfFortune {
private final int width;
private final int height;
private final int strokeWidth;
private final int color; //unused for now
private final int alpha;
private final int closure;
private final boolean fill;
private final int segments;
private final Sprite icon;
private final double arcLength;
private double drag = 0.97;
private double angleVel = 0;
private double angle = 0;
private int index = -1;
private int currentIndex = -1;
private final double INITIAL_DRAG = 0.993;
private final double LATER_DRAG = 0.988;
private final double DRAG_CHANGE_CUTOFF = 3.5;
private final double END_SPIN_CUTOFF = 0.4;
private int[] items = {6199, 6199, 6199, 6199, 6199, 6199, 6199, 6199, 6199, 6199}; // test
private boolean active;
public WheelOfFortune(int width, int height, int strokeWidth, int color, int alpha, int closure, boolean fill, int segments, Sprite icon) {
this.width = width;
this.height = height;
this.strokeWidth = strokeWidth;
this.color = color;
this.alpha = alpha;
this.closure = closure;
this.fill = fill;
this.segments = segments;
this.icon = icon;
arcLength = 360D / segments;
}
public void render(int x, int y) {
int idx = 0;
update();
for (double theta = 0; theta < 360; theta += arcLength) {
Raster.drawArc(x, y, width, height, strokeWidth, -(angle + theta), arcLength, 0x3f372c, alpha, closure, fill);
idx++;
}
for (int i = 0; i < items.length; i++) {
Sprite itemSprite = ItemDef.getSprite(items[i], 1, 0);
if (itemSprite == null) {
break;
}
double theta = i * arcLength;
double newPhi = ((angle + theta) + arcLength / 2D);
double newRadius = width / 3D;
double wheelCenterX = x + width / 2D;
double wheelCenterY = y + height / 2D;
double arcCenterX = (Math.cos(Math.toRadians(newPhi)) * newRadius + wheelCenterX);
double arcCenterY = (Math.sin(Math.toRadians(newPhi)) * newRadius + wheelCenterY);
itemSprite.drawSprite((int) (arcCenterX + 2) - itemSprite.myWidth / 2, (int) (arcCenterY + 2) - itemSprite.myHeight / 2);
}
icon.drawAdvancedSprite(x + (width / 2) - (icon.myWidth / 2), y - (height / 12), 255);
}
private void update() {
if (!active) {
return;
}
if (angleVel < END_SPIN_CUTOFF) {
angleVel = 0;
notifyServer();
active = false;
return;
}
if (angleVel < DRAG_CHANGE_CUTOFF) {
drag = LATER_DRAG;
}
angle += angleVel;
angleVel *= drag;
currentIndex = (int) (Math.floorMod((int) (-angle + (segments * 0.75D) * arcLength), 360) / arcLength);
}
public void init() {
this.drag = INITIAL_DRAG;
this.angle = 0;
double spinDurationAfterCutoff = Math.log(END_SPIN_CUTOFF / DRAG_CHANGE_CUTOFF) / Math.log(LATER_DRAG);
double angleAfterDragChange = DRAG_CHANGE_CUTOFF * (1 - Math.pow(LATER_DRAG, spinDurationAfterCutoff)) / (1 - LATER_DRAG);
double endAngle = ThreadLocalRandom.current().nextInt(3, 7) * 360 - angleAfterDragChange;
endAngle -= 90 + arcLength / 2; // center index 0 at the marker
endAngle -= index * arcLength; // select the index by shifting it so many segments over
double offset = ThreadLocalRandom.current()
.nextDouble(-arcLength / 2 + 5, arcLength / 2 - 5);
endAngle -= offset;
double tToCutoff = Math.log(DRAG_CHANGE_CUTOFF / (DRAG_CHANGE_CUTOFF + endAngle * (1 - drag))) / Math
.log(drag);
this.angleVel = DRAG_CHANGE_CUTOFF / Math.pow(drag, tToCutoff);
active = true;
}
public void setItems(int[] items) {
this.items = items;
}
public void setIndex(int index) {
this.index = index;
}
private void notifyServer() {
Client.stream.createPacket(225);
Client.stream.writeByte(index);
}
}
Code:
private static void wheelOfFortune(TextRaster[] font) {
final int STARTING_POINT = 21350;
RSInterface main = addInterface(STARTING_POINT);
addSpriteLoader(STARTING_POINT + 1, 1184);
addWheel(STARTING_POINT + 2, 210, 210, 2, 0x3f372c, 255, 2, true, 10, 1185);
main.totalChildren(13);
main.child(0, STARTING_POINT + 1, 50, 10);
main.child(1, STARTING_POINT + 2, 80, 65);
addHoverableSprite(STARTING_POINT + 3, 1187, 1188, true, "Spin Wheel");
main.child(2, STARTING_POINT + 3, 146, 283);
addTextComponent(STARTING_POINT + 4, "Spin Wheel!", fonts, 0, ColorConstants.RS_ORANGE, false, true, 0, 0);
main.child(3, STARTING_POINT + 4, 163, 290);
addNPC(STARTING_POINT + 5, 2998);
main.child(4, STARTING_POINT + 5, 335, 186);
addSpriteLoader(STARTING_POINT + 6, 1186);
main.child(5, STARTING_POINT + 6, 301, 168);
addSpriteLoader(STARTING_POINT + 7, 1190);
main.child(6, STARTING_POINT + 7, 282, 62);
addTextComponent(STARTING_POINT + 8, "Spin the wheel", fonts, 0, ColorConstants.RS_ORANGE, false, true, 0, 0);
main.child(7, STARTING_POINT + 8, 291, 72);
addTextComponent(STARTING_POINT + 9, "for a reward!", fonts, 0, ColorConstants.RS_ORANGE, false, true, 0, 0);
main.child(8, STARTING_POINT + 9, 296, 84);
addCloseButton(STARTING_POINT + 10);
main.child(9, STARTING_POINT + 10, 441, 19);
addTextComponent(STARTING_POINT + 11, "Wheel of fortune", fonts, 2, ColorConstants.RS_ORANGE, true, true, 0, 0);
main.child(10, STARTING_POINT + 11, 268, 19);
addTransparentLayer(STARTING_POINT + 12, 0, 120);
main.child(11, STARTING_POINT + 12, 50, 10);
main.child(12, STARTING_POINT + 20, 173, 48);
RSInterface rewardInterface = addInterface(STARTING_POINT + 20);
rewardInterface.setVisible(false);
rewardInterface.totalChildren(7);
addSpriteLoader(STARTING_POINT + 21, 1189);
rewardInterface.child(0, STARTING_POINT + 21, 0, 0);
addCloseButton(STARTING_POINT + 22);
rewardInterface.child(1, STARTING_POINT + 22, 164, 9);
addTextComponent(STARTING_POINT + 23, "Reward", fonts, 2, ColorConstants.RS_ORANGE, true, true, 0, 0);
rewardInterface.child(2, STARTING_POINT + 23, 94, 10);
addTextComponent(STARTING_POINT + 24, "You've won:", fonts, 2, ColorConstants.RS_ORANGE, false, true, 0, 0);
rewardInterface.child(3, STARTING_POINT + 24, 57, 43);
addHoverableSprite(STARTING_POINT + 25, 1187, 1188, true, "Spin Again!");
rewardInterface.child(4, STARTING_POINT + 25, 51, 198);
addTextComponent(STARTING_POINT + 26, "Spin Again!", fonts, 0, ColorConstants.RS_ORANGE, false, true, 0, 0);
rewardInterface.child(5, STARTING_POINT + 26, 69, 205);
addModel(STARTING_POINT + 27, 75, 50, 4447, 800, 3500);
rewardInterface.child(6, STARTING_POINT + 27, 63, 105);
}
Code:
public class WheelOfFortune {
private final int INTERFACE_ID = 21350;
private final int WHEEL_INTERFACE_ID = 21352;
private final int MODEL_COMPONENT_ID = 21377;
private int[] rewards = {18985, 21812, 21813, 21814, 19901, 21694, 21868, 18782, 21692};
private int[] rares = {21877, 5079, 3914, 21691, 19101, 4777, 3912};
private int itemId;
private final Player player;
//unused for now
private final int segments = 10;
private final SecureRandom secureRandom = new SecureRandom();
private WheelOfFortuneGame game = null;
public WheelOfFortune(Player player) {
this.player = player;
}
public void open(int[] normalRewards, int[] rareRewards, int itemId) {
this.rewards = normalRewards;
this.rares = rareRewards;
this.itemId = itemId;
player.getPacketSender().sendInterface(INTERFACE_ID);
player.getPacketSender().updateInterfaceVisibility(21370, false);
player.getPacketSender().updateInterfaceVisibility(21362, false);
}
public void start() {
if(!player.getInventory().contains(itemId)) {
return;
}
if (game != null) {
player.sendMessage("@red@The wheel is already spinning, wait for it to finish before spinning again");
return;
}
initGame();
}
private void initGame() {
List<Integer> left = Arrays.stream(rewards).boxed().collect(Collectors.toList());
int[] result = Stream.iterate(0, Integer::intValue)
.limit(rewards.length)
.mapToInt(i -> left.remove(secureRandom.nextInt(left.size())))
.toArray();
int randomRare = rares[secureRandom.nextInt(rares.length)];
int[] newRewards = new int[segments];
System.arraycopy(result, 0, newRewards, 0, result.length);
newRewards[newRewards.length - 1] = randomRare;
game = new WheelOfFortuneGame(newRewards);
player.getPacketSender()
.initWheelOfFortune(WHEEL_INTERFACE_ID, game.getWinningIndex(), game.getItems());
player.getInventory().delete(itemId, 1);
}
public void onFinish(int index) {
if (index != game.getWinningIndex()) {
return;
}
player.getPacketSender()
.sendInterfaceItemModel(MODEL_COMPONENT_ID, game.getReward().getId());
player.getPacketSender().updateInterfaceVisibility(21370, true);
player.getPacketSender().updateInterfaceVisibility(21362, true);
player.getInventory().add(game.getReward());
game = null;
}
}
Obviously i didn't include every single part, but those take 5mins to add at most