summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2024-11-10 20:45:32 +0500
committerilotterytea <iltsu@alright.party>2024-11-10 20:45:32 +0500
commit0a29485586012ae00548997c262ea16f3820a823 (patch)
treec1abed64ee34a53e8e119219a6278a03733b0754 /core/src
parentc5493df746e8f3915d86d8ebe85346dc1690ee4f (diff)
upd: kotlin has been a disaster for maxon source code
Diffstat (limited to 'core/src')
-rw-r--r--core/src/kz/ilotterytea/javaextra/tuples/Pair.java19
-rw-r--r--core/src/kz/ilotterytea/maxon/audio/Playlist.java57
-rw-r--r--core/src/kz/ilotterytea/maxon/audio/Playlist.kt40
-rw-r--r--core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java508
-rw-r--r--core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt468
-rw-r--r--core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java42
-rw-r--r--core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt37
-rw-r--r--core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java71
-rw-r--r--core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt66
9 files changed, 697 insertions, 611 deletions
diff --git a/core/src/kz/ilotterytea/javaextra/tuples/Pair.java b/core/src/kz/ilotterytea/javaextra/tuples/Pair.java
new file mode 100644
index 0000000..e312bad
--- /dev/null
+++ b/core/src/kz/ilotterytea/javaextra/tuples/Pair.java
@@ -0,0 +1,19 @@
+package kz.ilotterytea.javaextra.tuples;
+
+public class Pair<A, B> {
+ private A first;
+ private B second;
+
+ public Pair(A first, B second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public A getFirst() {
+ return first;
+ }
+
+ public B getSecond() {
+ return second;
+ }
+}
diff --git a/core/src/kz/ilotterytea/maxon/audio/Playlist.java b/core/src/kz/ilotterytea/maxon/audio/Playlist.java
new file mode 100644
index 0000000..62e8d14
--- /dev/null
+++ b/core/src/kz/ilotterytea/maxon/audio/Playlist.java
@@ -0,0 +1,57 @@
+package kz.ilotterytea.maxon.audio;
+
+import com.badlogic.gdx.audio.Music;
+import kz.ilotterytea.maxon.utils.math.Math;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Playlist {
+ private List<Music> music;
+ private Music playingNow;
+ private int index;
+
+ private boolean shuffleMode;
+ private float volume;
+
+ public Playlist(Music... music) {
+ this.music = Arrays.asList(music);
+
+ this.playingNow = this.music.get(0);
+ this.index = 0;
+ this.shuffleMode = false;
+ this.volume = 1f;
+
+ this.playingNow.setVolume(this.volume);
+ }
+
+ public void next() {
+ if (playingNow.isPlaying()) playingNow.stop();
+
+ if (shuffleMode) {
+ index = Math.getRandomNumber(0, music.size() - 1);
+ playingNow = music.get(index);
+ } else {
+ index++;
+ if (index > music.size() - 1) index = 0;
+
+ playingNow = music.get(index);
+ }
+
+ playingNow.setVolume(volume);
+ playingNow.play();
+ }
+
+ public void setVolume(float volume) {
+ this.volume = volume;
+ playingNow.setVolume(volume);
+ }
+
+ public void setShuffleMode(boolean shuffleMode) {
+ this.shuffleMode = shuffleMode;
+ }
+
+ public Music getPlayingNow() {
+ return playingNow;
+ }
+}
diff --git a/core/src/kz/ilotterytea/maxon/audio/Playlist.kt b/core/src/kz/ilotterytea/maxon/audio/Playlist.kt
deleted file mode 100644
index 2e79f37..0000000
--- a/core/src/kz/ilotterytea/maxon/audio/Playlist.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package kz.ilotterytea.maxon.audio
-
-import com.badlogic.gdx.audio.Music
-import kz.ilotterytea.maxon.utils.math.Math
-
-/**
- * Playlist.
- */
-class Playlist(vararg musics: Music) {
- private val playlist: Array<out Music> = musics
- var playingNow: Music = playlist[0]
- private var index = 0
-
- var shuffleMode = false
- var volume = 1f
- set(value) {
- playingNow.volume = value
- field = value
- }
-
- /**
- * Play next music.
- */
- fun next() {
- if (playingNow.isPlaying) playingNow.stop()
-
- if (shuffleMode) {
- index = Math.getRandomNumber(0, playlist.size - 1)
- playingNow = playlist[index]
- } else {
- index++
- if (index > playlist.size - 1) index = 0
-
- playingNow = playlist[index]
- }
-
- playingNow.volume = volume
- playingNow.play()
- }
-} \ No newline at end of file
diff --git a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java
new file mode 100644
index 0000000..ce564e5
--- /dev/null
+++ b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java
@@ -0,0 +1,508 @@
+package kz.ilotterytea.maxon.screens;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.Screen;
+import com.badlogic.gdx.assets.AssetManager;
+import com.badlogic.gdx.audio.Music;
+import com.badlogic.gdx.audio.Sound;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.TextureAtlas;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.ui.*;
+import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.utils.Align;
+import com.badlogic.gdx.utils.Timer;
+import com.badlogic.gdx.utils.viewport.FitViewport;
+import com.badlogic.gdx.utils.viewport.ScreenViewport;
+import com.badlogic.gdx.utils.viewport.Viewport;
+import kz.ilotterytea.javaextra.tuples.Pair;
+import kz.ilotterytea.maxon.MaxonGame;
+import kz.ilotterytea.maxon.constants.SettingsConstants;
+import kz.ilotterytea.maxon.localization.LineId;
+import kz.ilotterytea.maxon.player.Savegame;
+import kz.ilotterytea.maxon.screens.game.GameScreen;
+import kz.ilotterytea.maxon.tasks.MultiplierTask;
+import kz.ilotterytea.maxon.utils.OsUtils;
+import kz.ilotterytea.maxon.utils.formatters.NumberFormatter;
+import kz.ilotterytea.maxon.utils.math.Math;
+
+import java.util.ArrayList;
+
+public class SlotsMinigameScreen implements Screen {
+ private enum Slot {
+ Arbuz(5),
+ Icecream(30),
+ Kochan(80),
+ Buter(120),
+ Corn(200),
+ Kebab(500),
+ Onions(1000),
+ Treat(2500)
+ ;
+
+ private final int multiplier;
+
+ Slot(int multiplier) {
+ this.multiplier = multiplier;
+ }
+
+ public int getMultiplier() {
+ return multiplier;
+ }
+ }
+
+ private static class SlotImage extends Image {
+ public SlotImage(Slot slot, AssetManager assetManager) {
+ super(assetManager.get(
+ String.format("sprites/minigames/slots/%s.png", slot.name().toLowerCase()),
+ Texture.class
+ ));
+ }
+ }
+
+ private Savegame savegame;
+ private MaxonGame game;
+
+ private Stage stage;
+ private TextButton spinButton, exitButton;
+ private Label prizeLabel, moneyLabel;
+ private TextField stakeField;
+ private Table columns;
+
+ private double prize, stake;
+ private int loseStreak, maxLoseStreak, lockedColumns;
+ private boolean disabled;
+
+ private Slot loseSlot;
+
+ private ArrayList<Slot> columnSlots;
+ private ArrayList<Pair<Timer.Task, Float>> tasks;
+
+ private MultiplierTask multiplierTask;
+
+ private Music audioLoop;
+ private float soundVolume;
+
+ @Override
+ public void show() {
+ this.savegame = Savegame.getInstance();
+ this.game = MaxonGame.getInstance();
+ this.columnSlots = new ArrayList<>();
+ this.tasks = new ArrayList<>();
+ this.multiplierTask = new MultiplierTask(savegame);
+ this.loseSlot = Slot.values()[0];
+
+ Viewport viewport;
+
+ if (OsUtils.isMobile) {
+ viewport = new ScreenViewport();
+ } else {
+ viewport = new FitViewport(800f, 600f);
+ }
+
+ this.stage = new Stage(viewport);
+
+ Skin skin = game.assetManager.get("sprites/gui/ui.skin");
+
+ Table table = new Table();
+ table.setFillParent(true);
+ table.align(Align.center);
+
+ if (OsUtils.isMobile) table.pad(64f);
+
+ stage.addActor(table);
+
+ // Background
+ if (OsUtils.isPC) {
+ Image background = new Image(game.assetManager.get("sprites/minigames/slots/background.png", Texture.class));
+ background.setZIndex(2);
+
+ table.add(background);
+ }
+
+ String styleName = OsUtils.isMobile ? "defaultMobile" : "default";
+
+ // Buttons
+ spinButton = new TextButton(game.getLocale().getLine(LineId.MinigameSlotsSpinbutton), skin, styleName);
+ spinButton.setDisabled(true);
+ spinButton.setWidth(420f);
+ spinButton.setPosition(62f, 60f);
+ spinButton.addListener(new ClickListener() {
+ @Override
+ public void clicked(InputEvent event, float x, float y) {
+ if (spinButton.isDisabled()) return;
+ super.clicked(event, x, y);
+ restart();
+ }
+ });
+
+ exitButton = new TextButton(game.getLocale().getLine(LineId.MinigameSlotsExitbutton), skin, styleName);
+ exitButton.setPosition(62f, stage.getHeight() / 2f - 150f);
+ exitButton.addListener(new ClickListener() {
+ @Override
+ public void clicked(InputEvent event, float x, float y) {
+ if (exitButton.isDisabled()) return;
+ super.clicked(event, x, y);
+ game.setScreen(new GameScreen());
+ }
+ });
+
+ // Labels
+ styleName = OsUtils.isMobile ? "slotsMobile" : "slots";
+
+ prizeLabel = new Label("", skin, styleName);
+ prizeLabel.setAlignment(Align.center);
+ prizeLabel.setPosition(stage.getWidth() / 2f - 180f, stage.getHeight() / 2f + 80f);
+
+ Image moneyIcon = new Image(game.assetManager.get("sprites/gui/player_icons.atlas", TextureAtlas.class).findRegion("points"));
+ moneyIcon.setSize(20f, 20f);
+ moneyIcon.setPosition(stage.getWidth() / 2f + 60f, stage.getHeight() / 2f - 180f);
+
+ moneyLabel = new Label(NumberFormatter.format(savegame.getMoney()), skin, styleName);
+ moneyLabel.setAlignment(Align.right);
+ moneyLabel.setPosition(stage.getWidth() / 2f, stage.getHeight() / 2f - 180f);
+
+ Label stakeLabel = new Label(game.getLocale().getLine(LineId.MinigameSlotsBet), skin, styleName);
+ stakeLabel.setAlignment(Align.center);
+ stakeLabel.setPosition(stage.getWidth() / 2f - 40f, stage.getHeight() / 2f - 100f);
+
+ stakeField = new TextField("", skin, OsUtils.isMobile ? "defaultMobile" : "default");
+ stakeField.setMessageText("---");
+ stakeField.setTextFieldFilter((x, c) -> String.valueOf(c).matches("^[0-9]*$"));
+ stakeField.addListener(new ChangeListener() {
+ @Override
+ public void changed(ChangeEvent event, Actor actor) {
+ if (actor instanceof TextField tf) {
+ if (tf.isDisabled()) return;
+
+ String value = tf.getText();
+
+ try {
+ long v = Long.parseLong(value);
+
+ if (v > savegame.getMoney()) {
+ v = Double.valueOf(savegame.getMoney()).longValue();
+ }
+
+ tf.setText(Long.toString(v));
+ stake = (double) v;
+
+ spinButton.setDisabled(stake <= 0.0);
+ } catch (Exception ignored) {}
+ }
+ }
+ });
+ stakeField.setPosition(stage.getWidth() / 2f - 70f, stage.getHeight() / 2f - 150f);
+
+ // Slot columns
+ columns = new Table();
+
+ if (OsUtils.isPC) {
+ columns.setX(62f);
+ columns.setY(stage.getHeight() / 2f);
+ columns.setWidth(424f);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ columnSlots.add(Slot.values()[Math.getRandomNumber(0, Slot.values().length)]);
+ }
+
+ reRoll();
+
+ Timer.Task updateTask = new Timer.Task() {
+ @Override
+ public void run() {
+ reRoll();
+ }
+ };
+
+ tasks.add(new Pair<>(updateTask, 0.1f));
+
+ Timer.Task lockColumnTask = new Timer.Task() {
+ @Override
+ public void run() {
+ Sound sound = game.assetManager.get("sfx/minigames/slots/slots_lock.ogg", Sound.class);
+ sound.play(soundVolume);
+
+ lockedColumns += 1;
+
+ if (lockedColumns > 1) {
+ finish();
+ }
+ }
+ };
+
+ tasks.add(new Pair<>(lockColumnTask, 2f));
+
+ disableSlotMachineIfNoStake();
+
+ audioLoop = game.assetManager.get("mus/minigames/slots/slots_loop.mp3");
+ audioLoop.setLooping(true);
+ audioLoop.setVolume(game.prefs.getInteger("music", 10) / 10f);
+ soundVolume = game.prefs.getInteger("sfx", 10) / 10f;
+
+ Timer.schedule(multiplierTask, 0.1f, 0.1f);
+
+ if (OsUtils.isMobile) {
+ Image title = new Image(game.assetManager.get("sprites/minigames/slots/title.png", Texture.class));
+ table.add(title).growX().height(
+ title.getHeight() * (this.stage.getWidth() - 64f) / title.getWidth()
+ ).padBottom(64f).row();
+
+ table.add(prizeLabel).expandX().padBottom(64f).row();
+
+ table.add(columns).growX().padBottom(64f).row();
+ columns.align(Align.center);
+
+ table.add(stakeLabel).growX().padBottom(32f).row();
+ stakeLabel.setAlignment(Align.right);
+
+ Table table2 = new Table();
+ table2.add(exitButton).align(Align.left).expandX();
+ table2.add(stakeField).align(Align.right).minWidth(300f);
+ table.add(table2).growX().padBottom(32f).row();
+
+ Table table3 = new Table();
+ table3.align(Align.right);
+ table3.add(moneyLabel).padRight(16f);
+ table3.add(moneyIcon);
+ table.add(table3).growX().padBottom(64f).row();
+
+ table.add(spinButton).growX();
+ } else {
+ stage.addActor(spinButton);
+ stage.addActor(exitButton);
+ stage.addActor(prizeLabel);
+ stage.addActor(moneyIcon);
+ stage.addActor(moneyLabel);
+ stage.addActor(stakeLabel);
+ stage.addActor(stakeField);
+ stage.addActor(columns);
+ }
+
+ Gdx.input.setInputProcessor(stage);
+ }
+
+ @Override
+ public void render(float delta) {
+ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
+ if (OsUtils.isMobile) {
+ Gdx.gl.glClearColor(0.12f, 0.12f, 0.15f, 1f);
+ } else {
+ Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
+ }
+
+ stage.act(delta);
+ stage.draw();
+
+ moneyLabel.setText(NumberFormatter.format(savegame.getMoney(), false));
+ }
+
+
+ private void finish() {
+ if (audioLoop.isPlaying()) audioLoop.stop();
+
+ stakeField.setDisabled(false);
+ exitButton.setDisabled(false);
+ spinButton.setDisabled(false);
+
+ for (Pair<Timer.Task, Float> x : tasks) {
+ x.getFirst().cancel();
+ }
+
+ giveReward();
+ updateLabels();
+ disableSlotMachineIfNoStake();
+ }
+
+ private void restart() {
+ audioLoop.play();
+
+ Sound sound = game.assetManager.get("sfx/minigames/slots/slots_start.ogg");
+ sound.play(soundVolume);
+
+ prizeLabel.setText("");
+
+ exitButton.setDisabled(true);
+ spinButton.setDisabled(true);
+ stakeField.setDisabled(true);
+
+ loseSlot = Slot.values()[Math.getRandomNumber(0,3)];
+ lockedColumns = -1;
+ loseStreak = 0;
+ prize = 0.0;
+ maxLoseStreak = Math.getRandomNumber(20, 50);
+
+ reRoll();
+
+ for (Pair<Timer.Task, Float> task : tasks) {
+ Timer.schedule(task.getFirst(), task.getSecond(), task.getSecond());
+ }
+ }
+
+ private void reRoll() {
+ ArrayList<Slot> array = new ArrayList<>();
+
+ for (int i = 0; i < columnSlots.size(); i++) {
+ while (true) {
+ Slot x = columnSlots.get(i);
+
+ if (i <= lockedColumns) {
+ if (loseStreak >= maxLoseStreak) {
+ x = loseSlot;
+ }
+
+ array.add(x);
+ break;
+ }
+
+ Slot slot = Slot.values()[Math.getRandomNumber(0, Slot.values().length)];
+
+ if (x.ordinal() != slot.ordinal()) {
+ array.add(slot);
+ break;
+ }
+ }
+ }
+
+ columnSlots.clear();
+ columns.clear();
+
+ float size = (OsUtils.isMobile ? 300f : 100f) * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE);
+
+ for (Slot x : array) {
+ columnSlots.add(x);
+ columns.add(new SlotImage(x, game.assetManager))
+ .size(size, size)
+ .expandX();
+ }
+ }
+
+ private void disableSlotMachineIfNoStake() {
+ if ((long) savegame.getMoney() > 0) {
+ return;
+ }
+
+ disabled = true;
+
+ stakeField.setMessageText("---");
+ stakeField.setText("---");
+ stakeField.setDisabled(disabled);
+ spinButton.setDisabled(disabled);
+
+ for (Pair<Timer.Task, Float> x : tasks) {
+ x.getFirst().cancel();
+ }
+ }
+
+ private void giveReward() {
+ Slot first = columnSlots.get(0);
+ boolean same = false;
+
+ for (Slot x : columnSlots) {
+ same = x.ordinal() == first.ordinal();
+
+ if (!same) {
+ break;
+ }
+ }
+
+ playRewardSound(same, first);
+
+ savegame.setSlotsTotalSpins(savegame.getSlotsTotalSpins() + 1);
+
+ if (!same) {
+ loseStreak++;
+ savegame.decreaseMoney(stake);
+ return;
+ }
+
+ prize = stake * first.multiplier;
+ savegame.increaseMoney(prize);
+ savegame.setSlotsWins(savegame.getSlotsWins() + 1);
+ }
+
+ private void updateLabels() {
+ String prizeText;
+
+ if (prize == 0.0) {
+ prizeText = game.getLocale().getLine(LineId.MinigameSlotsNothing);
+ } else {
+ prizeText = game.getLocale().getFormattedLine(LineId.MinigameSlotsPrize, NumberFormatter.format(prize, false));
+ }
+
+ prizeLabel.setText(prizeText);
+
+ if (stake > savegame.getMoney()) {
+ stake = savegame.getMoney();
+
+ long money = (long) savegame.getMoney();
+ String stakeText;
+ if (money <= 0) {
+ stakeText = "---";
+ } else {
+ stakeText = String.valueOf(money);
+ }
+
+ stakeField.setText(stakeText);
+ }
+
+ moneyLabel.setText(NumberFormatter.format(savegame.getMoney(), false));
+ }
+
+ private void playRewardSound(boolean same, Slot slot) {
+ String path;
+ if (!same) {
+ path = "fail";
+ } else {
+ path = switch (slot.ordinal()) {
+ case 0, 1 -> "small_win";
+ case 2, 3, 4 -> "medium_win";
+ default -> "big_win";
+ };
+ }
+
+ Sound sound = game.assetManager.get(String.format("sfx/minigames/slots/slots_%s.ogg", path));
+ sound.play(soundVolume);
+ }
+
+ @Override
+ public void resize(int width, int height) {
+ stage.getViewport().update(width, height, true);
+ }
+
+ @Override
+ public void pause() {
+ dispose();
+ }
+
+ @Override
+ public void resume() {
+ show();
+ }
+
+ @Override
+ public void hide() {
+ savegame.save();
+ dispose();
+ }
+
+ @Override
+ public void dispose() {
+ for (Pair<Timer.Task, Float> x : tasks) {
+ x.getFirst().cancel();
+ }
+
+ tasks.clear();
+ multiplierTask.cancel();
+ stage.dispose();
+ audioLoop.stop();
+
+ Gdx.input.setOnscreenKeyboardVisible(false);
+ Gdx.input.setInputProcessor(null);
+ }
+}
diff --git a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt
deleted file mode 100644
index 6a03025..0000000
--- a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt
+++ /dev/null
@@ -1,468 +0,0 @@
-@file:Suppress("unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused",
- "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused"
-)
-
-package kz.ilotterytea.maxon.screens
-
-import com.badlogic.gdx.Gdx
-import com.badlogic.gdx.Screen
-import com.badlogic.gdx.assets.AssetManager
-import com.badlogic.gdx.audio.Music
-import com.badlogic.gdx.audio.Sound
-import com.badlogic.gdx.graphics.GL20
-import com.badlogic.gdx.graphics.Texture
-import com.badlogic.gdx.graphics.g2d.TextureAtlas
-import com.badlogic.gdx.scenes.scene2d.Actor
-import com.badlogic.gdx.scenes.scene2d.InputEvent
-import com.badlogic.gdx.scenes.scene2d.Stage
-import com.badlogic.gdx.scenes.scene2d.ui.*
-import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
-import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
-import com.badlogic.gdx.utils.Align
-import com.badlogic.gdx.utils.Timer
-import com.badlogic.gdx.utils.Timer.Task
-import com.badlogic.gdx.utils.viewport.FitViewport
-import com.badlogic.gdx.utils.viewport.ScreenViewport
-import kz.ilotterytea.maxon.MaxonGame
-import kz.ilotterytea.maxon.constants.SettingsConstants
-import kz.ilotterytea.maxon.localization.LineId
-import kz.ilotterytea.maxon.player.Savegame
-import kz.ilotterytea.maxon.screens.game.GameScreen
-import kz.ilotterytea.maxon.tasks.MultiplierTask
-import kz.ilotterytea.maxon.utils.OsUtils
-import kz.ilotterytea.maxon.utils.formatters.NumberFormatter
-import kotlin.math.roundToInt
-import kotlin.math.roundToLong
-import kotlin.random.Random
-
-private enum class Slot(val multiplier: Int) {
- Arbuz(5),
- Icecream(30),
- Kochan(80),
- Buter(120),
- Corn(200),
- Kebab(500),
- Onions(1000),
- Treat(2500),
-}
-
-private class SlotImage(slot: Slot, assetManager: AssetManager) : Image(assetManager.get("sprites/minigames/slots/${slot.name.lowercase()}.png", Texture::class.java))
-
-@Suppress("unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused",
- "unused", "unused", "unused", "unused", "unused", "unused", "unused"
-)
-class SlotsMinigameScreen : Screen {
- private val savegame = Savegame.getInstance()
-
- private val game = MaxonGame.getInstance()
- private val stage = Stage(if (OsUtils.isMobile) {
- ScreenViewport()
- } else {
- FitViewport(800f, 600f)
- })
-
- private var spinButton: TextButton? = null
- private var exitButton: TextButton? = null
-
- private var prize = 0.0
- private var prizeLabel: Label? = null
- private var moneyLabel: Label? = null
-
- private var stake = 0.0
- private var stakeField: TextField? = null
-
- private var loseSlot = Slot.values()[0]
- private var loseStreak = 0
- private var maxLoseStreak = Random.nextInt(20, 50)
-
- private var disabled = false
- private var lockedColumns = -1
- private val columnSlots = arrayListOf<Slot>()
- private val columns = Table()
-
- private val tasks = arrayListOf<Pair<Task, Float>>()
-
- private val audioLoop: Music = game.assetManager.get("mus/minigames/slots/slots_loop.mp3")
-
- private val soundVolume = game.prefs.getInteger("sfx", 10) / 10f
-
- private val multiplierTask = MultiplierTask(savegame)
-
- override fun show() {
- // Skins
- val skin = game.assetManager.get("sprites/gui/ui.skin", Skin::class.java)
-
- // Main table
- val table = Table()
- table.setFillParent(true)
- table.align(Align.center)
-
- if (OsUtils.isMobile) table.pad(64f)
-
- stage.addActor(table)
-
- // Background
- if (OsUtils.isPC) {
- val background = Image(game.assetManager.get("sprites/minigames/slots/background.png", Texture::class.java))
- background.zIndex = 2
-
- table.add(background)
- }
-
- var styleName = if (OsUtils.isMobile) "defaultMobile" else "default"
-
- // Buttons
- spinButton = TextButton(game.locale.getLine(LineId.MinigameSlotsSpinbutton), skin, styleName)
- spinButton?.isDisabled = true
- spinButton?.width = 420f
- spinButton?.setPosition(62f, 60f)
- spinButton?.addListener(object : ClickListener() {
- override fun clicked(event: InputEvent?, x: Float, y: Float) {
- if (spinButton?.isDisabled == true) return
- super.clicked(event, x, y)
- restart()
- }
- })
-
- exitButton = TextButton(game.locale.getLine(LineId.MinigameSlotsExitbutton), skin, styleName)
- exitButton?.setPosition(62f, stage.height / 2f - 150f)
- exitButton?.addListener(object : ClickListener() {
- override fun clicked(event: InputEvent?, x: Float, y: Float) {
- if (exitButton?.isDisabled == true) return
- super.clicked(event, x, y)
- game.screen = GameScreen()
- }
- })
-
- // Labels
- styleName = if (OsUtils.isMobile) "slotsMobile" else "slots"
-
- prizeLabel = Label("", skin, styleName)
- prizeLabel?.setAlignment(Align.center)
- prizeLabel?.setPosition(stage.width / 2f - 180f, stage.height / 2f + 80f)
-
- val moneyIcon = Image(game.assetManager.get("sprites/gui/player_icons.atlas", TextureAtlas::class.java).findRegion("points"))
- moneyIcon.setSize(20f, 20f)
- moneyIcon.setPosition(stage.width / 2f + 60f, stage.height / 2f - 180f)
-
- moneyLabel = Label(NumberFormatter.format(savegame.money), skin, styleName)
- moneyLabel?.setAlignment(Align.right)
- moneyLabel?.setPosition(stage.width / 2f, stage.height / 2f - 180f)
-
- val stakeLabel = Label(game.locale.getLine(LineId.MinigameSlotsBet), skin, styleName)
- stakeLabel.setAlignment(Align.center)
- stakeLabel.setPosition(stage.width / 2f - 40f, stage.height / 2f - 100f)
-
- stakeField = TextField("", skin, if (OsUtils.isMobile) "defaultMobile" else "default")
- stakeField?.messageText = "---"
- stakeField?.setTextFieldFilter { _, c -> c.toString().matches(Regex("^[0-9]*\$")) }
- stakeField?.addListener(object : ChangeListener() {
- override fun changed(event: ChangeEvent?, actor: Actor?) {
- val textField = actor as TextField
- if (textField.isDisabled) return
-
- var value = textField.text?.toLongOrNull()
-
- if (value != null) {
- if (value > savegame.money.toLong()) {
- value = savegame.money.roundToLong()
- }
-
- textField.text = value.toString()
- stake = value.toDouble()
-
- spinButton?.isDisabled = stake <= 0.0
- }
- }
- })
- stakeField?.setPosition(stage.width / 2f - 70f, stage.height / 2f - 150f)
-
- // Slot columns
- if (OsUtils.isPC) {
- columns.x = 62f
- columns.y = stage.height / 2f
- columns.width = 424f
- }
-
- for (i in 0..2) {
- columnSlots.add(Slot.values()[Random.nextInt(0, Slot.values().size)])
- }
-
- reRoll()
-
- val updateTask = object : Task() {
- override fun run() {
- reRoll()
- }
- }
-
- tasks.add(Pair(updateTask, 0.1f))
-
- val lockColumnTask = object : Task() {
- override fun run() {
- val sound = game.assetManager.get("sfx/minigames/slots/slots_lock.ogg", Sound::class.java)
- sound.play(soundVolume)
-
- lockedColumns += 1
-
- if (lockedColumns > 1) {
- finish()
- }
- }
- }
-
- tasks.add(Pair(lockColumnTask, 2f))
-
- disableSlotMachineIfNoStake()
-
- audioLoop.isLooping = true
- audioLoop.volume = game.prefs.getInteger("music", 10) / 10f
-
- Timer.schedule(multiplierTask, 0.1f, 0.1f)
-
- if (OsUtils.isMobile) {
- val title = Image(game.assetManager.get("sprites/minigames/slots/title.png", Texture::class.java))
- table.add(title).growX().height(title.height * (this.stage.width - 64f) / title.width).padBottom(64f).row()
-
- table.add(prizeLabel).expandX().padBottom(64f).row()
-
- table.add(columns).growX().padBottom(64f).row()
- columns.align(Align.center)
-
- table.add(stakeLabel).growX().padBottom(32f).row()
- stakeLabel.setAlignment(Align.right)
-
- val table2 = Table()
- table2.add(exitButton).align(Align.left).expandX()
- table2.add(stakeField).align(Align.right).minWidth(300f)
- table.add(table2).growX().padBottom(32f).row()
-
- val table3 = Table()
- table3.align(Align.right)
- table3.add(moneyLabel).padRight(16f)
- table3.add(moneyIcon)
- table.add(table3).growX().padBottom(64f).row()
-
- table.add(spinButton).growX()
- } else {
- stage.addActor(spinButton)
- stage.addActor(exitButton)
- stage.addActor(prizeLabel)
- stage.addActor(moneyIcon)
- stage.addActor(moneyLabel)
- stage.addActor(stakeLabel)
- stage.addActor(stakeField)
- stage.addActor(columns)
- }
-
- Gdx.input.inputProcessor = stage
- }
-
- override fun render(delta: Float) {
- Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT)
- if (OsUtils.isMobile) {
- Gdx.gl.glClearColor(0.12f, 0.12f, 0.15f, 1f)
- } else {
- Gdx.gl.glClearColor(0f, 0f, 0f, 1f)
- }
-
- stage.act(delta)
- stage.draw()
-
- moneyLabel?.setText(NumberFormatter.format(savegame.money, false))
- }
-
- private fun reRoll() {
- val array = arrayListOf<Slot>()
-
- for (i in 0 until columnSlots.size) {
- while (true) {
- var x = columnSlots[i]
-
- if (i <= lockedColumns) {
- if (loseStreak >= maxLoseStreak) {
- x = loseSlot
- }
-
- array.add(x)
- break
- }
-
- val slot = Slot.values()[Random.nextInt(0, Slot.values().size)]
-
- if (x.ordinal != slot.ordinal) {
- array.add(slot)
- break
- }
- }
- }
-
- columnSlots.clear()
- columns.clear()
-
- val size = (if (OsUtils.isMobile) 300f else 100f) * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE)
-
- for (x in array) {
- columnSlots.add(x)
- columns.add(SlotImage(x, game.assetManager))
- .size(size, size)
- .expandX()
- }
- }
-
-
- private fun finish() {
- if (audioLoop.isPlaying) audioLoop.stop()
-
- stakeField?.isDisabled = false
- exitButton?.isDisabled = false
- spinButton?.isDisabled = false
-
- for (x in tasks) {
- x.first.cancel()
- }
-
- giveReward()
- updateLabels()
- disableSlotMachineIfNoStake()
- }
-
- private fun restart() {
- audioLoop.play()
-
- val sound = game.assetManager.get<Sound>("sfx/minigames/slots/slots_start.ogg")
- sound.play(soundVolume)
-
- prizeLabel?.setText("")
-
- exitButton?.isDisabled = true
- spinButton?.isDisabled = true
- stakeField?.isDisabled = true
-
- loseSlot = Slot.values()[Random.nextInt(0,3)]
- lockedColumns = -1
- loseStreak = 0
- prize = 0.0
- maxLoseStreak = Random.nextInt(20, 50)
-
- reRoll()
-
- for (task in tasks) {
- Timer.schedule(task.first, task.second, task.second)
- }
- }
-
- private fun giveReward() {
- val first = columnSlots[0]
- var same = false
-
- for (x in columnSlots) {
- same = x.ordinal == first.ordinal
-
- if (!same) {
- break
- }
- }
-
- playRewardSound(same, first)
-
- savegame.slotsTotalSpins++
-
- if (!same) {
- loseStreak++
- savegame.money -= stake
- return
- }
-
- prize = stake * first.multiplier
- savegame.money += prize
- savegame.slotsWins++
- }
-
- private fun updateLabels() {
- val prizeText = if (prize == 0.0) {
- game.locale.getLine(LineId.MinigameSlotsNothing)
- } else {
- game.locale.getFormattedLine(LineId.MinigameSlotsPrize, NumberFormatter.format(prize, false))
- }
-
- prizeLabel?.setText(prizeText)
-
- if (stake.toLong() > savegame.money.toLong()) {
- stake = savegame.money
-
- val stakeText = if (savegame.money.roundToInt() <= 0) {
- "---"
- } else {
- savegame.money.roundToInt().toString()
- }
-
- stakeField?.text = stakeText
- }
-
- moneyLabel?.setText(NumberFormatter.format(savegame.money, false))
- }
-
- private fun disableSlotMachineIfNoStake() {
- if (savegame.money.toLong() > 0) {
- return
- }
-
- disabled = true
-
- stakeField?.messageText = "---"
- stakeField?.text = "---"
- stakeField?.isDisabled = disabled
- spinButton?.isDisabled = disabled
-
- for (x in tasks) {
- x.first.cancel()
- }
- }
-
- private fun playRewardSound(same: Boolean, slot: Slot) {
- val path = if (!same) {
- "fail"
- } else {
- when (slot.ordinal) {
- in 0..1 -> "small_win"
- in 2..4 -> "medium_win"
- else -> "big_win"
- }
- }
-
- val sound = game.assetManager.get("sfx/minigames/slots/slots_$path.ogg", Sound::class.java)
- sound.play(soundVolume)
- }
-
- override fun resize(width: Int, height: Int) {
- stage.viewport.update(width, height, true)
- }
-
- override fun pause() {
- dispose()
- }
-
- override fun resume() {
- show()
- }
-
- override fun hide() {
- savegame.save()
- dispose()
- }
-
- override fun dispose() {
- for (x in tasks) {
- x.first.cancel()
- }
-
- tasks.clear()
- multiplierTask.cancel()
- stage.dispose()
- audioLoop.stop()
-
- Gdx.input.setOnscreenKeyboardVisible(false)
- Gdx.input.inputProcessor = null
- }
-} \ No newline at end of file
diff --git a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java
new file mode 100644
index 0000000..2a28586
--- /dev/null
+++ b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java
@@ -0,0 +1,42 @@
+package kz.ilotterytea.maxon.ui;
+
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.scenes.scene2d.ui.Skin;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+
+public class ShakingImageButton extends Image {
+ public ShakingImageButton(Skin skin, String style) {
+ super(skin.getRegion(style));
+
+ this.setOrigin(getWidth() / 2f, getHeight() / 2f);
+
+ this.addListener(new ClickListener() {
+ @Override
+ public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
+ super.enter(event, x, y, pointer, fromActor);
+
+ addAction(
+ Actions.repeat(
+ RepeatAction.FOREVER,
+ Actions.sequence(
+ Actions.rotateTo(-2f, 0.1f),
+ Actions.rotateTo(2f, 0.1f)
+ )
+ )
+ );
+ }
+
+ @Override
+ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
+ super.exit(event, x, y, pointer, toActor);
+
+ clearActions();
+ addAction(Actions.rotateTo(0f, 0.1f));
+ }
+ });
+ }
+}
diff --git a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt
deleted file mode 100644
index eb8c51c..0000000
--- a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package kz.ilotterytea.maxon.ui
-
-import com.badlogic.gdx.scenes.scene2d.Actor
-import com.badlogic.gdx.scenes.scene2d.InputEvent
-import com.badlogic.gdx.scenes.scene2d.actions.Actions
-import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction
-import com.badlogic.gdx.scenes.scene2d.ui.Image
-import com.badlogic.gdx.scenes.scene2d.ui.Skin
-import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
-
-class ShakingImageButton(skin: Skin, style: String) : Image(skin.getRegion(style)) {
- init {
- setOrigin(width / 2f, height / 2f)
-
- addListener(object : ClickListener() {
- override fun enter(event: InputEvent?, x: Float, y: Float, pointer: Int, fromActor: Actor?) {
- super.enter(event, x, y, pointer, fromActor)
-
- addAction(
- Actions.repeat(
- RepeatAction.FOREVER,
- Actions.sequence(
- Actions.rotateTo(-2f, 0.1f),
- Actions.rotateTo(2f, 0.1f)
- )
- )
- )
- }
-
- override fun exit(event: InputEvent?, x: Float, y: Float, pointer: Int, toActor: Actor?) {
- super.exit(event, x, y, pointer, toActor)
- clearActions()
- addAction(Actions.rotateTo(0f, 0.1f))
- }
- })
- }
-} \ No newline at end of file
diff --git a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java
new file mode 100644
index 0000000..1940d65
--- /dev/null
+++ b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java
@@ -0,0 +1,71 @@
+package kz.ilotterytea.maxon.ui.game;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.audio.Sound;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.ui.Cell;
+import com.badlogic.gdx.scenes.scene2d.ui.Skin;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.utils.Align;
+import kz.ilotterytea.maxon.MaxonGame;
+import kz.ilotterytea.maxon.constants.SettingsConstants;
+import kz.ilotterytea.maxon.screens.MenuScreen;
+import kz.ilotterytea.maxon.screens.SlotsMinigameScreen;
+import kz.ilotterytea.maxon.ui.ShakingImageButton;
+import kz.ilotterytea.maxon.utils.OsUtils;
+
+public class QuickActionsTable extends Table {
+ public QuickActionsTable(Skin widgetSkin, Skin uiSkin) {
+ super(uiSkin);
+
+ MaxonGame game = MaxonGame.getInstance();
+
+ Sound clickSound = game.assetManager.get("sfx/ui/click.ogg");
+ float soundVolume = game.prefs.getInteger("sfx", 10) / 10f;
+
+ float iconSize = (OsUtils.isMobile ? 256f : 64f)
+ * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE);
+
+ ShakingImageButton slotsButton = new ShakingImageButton(widgetSkin, "slots");
+ slotsButton.setOrigin(iconSize / 2f, iconSize / 2f);
+ slotsButton.addListener(new ClickListener() {
+ @Override
+ public void clicked(InputEvent event, float x, float y) {
+ super.clicked(event, x, y);
+ clickSound.play(soundVolume);
+ game.setScreen(new SlotsMinigameScreen());
+ }
+ });
+ Cell<ShakingImageButton> slotsCell = add(slotsButton).size(iconSize).padRight(8f);
+
+ ShakingImageButton quitButton = new ShakingImageButton(widgetSkin, "exit");
+ quitButton.setOrigin(iconSize / 2f, iconSize / 2f);
+ quitButton.addListener(new ClickListener() {
+ @Override
+ public void clicked(InputEvent event, float x, float y) {
+ super.clicked(event, x, y);
+ clickSound.play(soundVolume);
+ game.setScreen(new MenuScreen());
+ }
+ });
+ Cell<ShakingImageButton> quitCell = add(quitButton).size(iconSize);
+
+ if (OsUtils.isMobile) {
+ slotsCell.expandX();
+ quitCell.expandX();
+ }
+ }
+
+ @Override
+ public void draw(Batch batch, float parentAlpha) {
+ super.draw(batch, parentAlpha);
+
+ if (OsUtils.isMobile) return;
+
+ // i'm not sure how much does it affect on performance
+ setX(Gdx.graphics.getWidth() - 36f * 2f, Align.left);
+ setY(Gdx.graphics.getHeight() - 36f, Align.top);
+ }
+}
diff --git a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt
deleted file mode 100644
index 08b4bb7..0000000
--- a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package kz.ilotterytea.maxon.ui.game
-
-import com.badlogic.gdx.Gdx
-import com.badlogic.gdx.audio.Sound
-import com.badlogic.gdx.graphics.g2d.Batch
-import com.badlogic.gdx.scenes.scene2d.InputEvent
-import com.badlogic.gdx.scenes.scene2d.ui.Skin
-import com.badlogic.gdx.scenes.scene2d.ui.Table
-import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
-import com.badlogic.gdx.utils.Align
-import kz.ilotterytea.maxon.MaxonGame
-import kz.ilotterytea.maxon.constants.SettingsConstants
-import kz.ilotterytea.maxon.screens.MenuScreen
-import kz.ilotterytea.maxon.screens.SlotsMinigameScreen
-import kz.ilotterytea.maxon.ui.ShakingImageButton
-import kz.ilotterytea.maxon.utils.OsUtils
-
-class QuickActionsTable(widgetSkin: Skin, uiSkin: Skin) : Table(uiSkin) {
- init {
- val game = MaxonGame.getInstance()
- val clickSound = game.assetManager.get("sfx/ui/click.ogg", Sound::class.java)
- val soundVolume = game.prefs.getInteger("sfx", 10) / 10f
- val iconSize = if (OsUtils.isMobile) {
- 256f
- } else {
- 64f
- } * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE)
-
- val slotsButton = ShakingImageButton(widgetSkin, "slots")
- slotsButton.setOrigin(iconSize / 2f, iconSize / 2f)
- slotsButton.addListener(object : ClickListener() {
- override fun clicked(event: InputEvent, x: Float, y: Float) {
- super.clicked(event, x, y)
- clickSound.play(soundVolume)
- game.screen = SlotsMinigameScreen()
- }
- })
- val slotsCell = add(slotsButton).size(iconSize).padRight(8f)
-
- val quitButton = ShakingImageButton(widgetSkin, "exit")
- quitButton.setOrigin(iconSize / 2f, iconSize / 2f)
- quitButton.addListener(object : ClickListener() {
- override fun clicked(event: InputEvent, x: Float, y: Float) {
- super.clicked(event, x, y)
- clickSound.play(soundVolume)
- game.screen = MenuScreen()
- }
- })
- val quitCell = add(quitButton).size(iconSize)
-
- if (OsUtils.isMobile) {
- slotsCell.expandX()
- quitCell.expandX()
- }
- }
-
- override fun draw(batch: Batch?, parentAlpha: Float) {
- super.draw(batch, parentAlpha)
-
- if (OsUtils.isMobile) return
-
- // i'm not sure how much does it affect on performance
- setX(Gdx.graphics.width - 36f * 2f, Align.left)
- setY(Gdx.graphics.height - 36f, Align.top)
- }
-} \ No newline at end of file