summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/i18n/en_us.json6
-rw-r--r--assets/i18n/ru_ru.json6
-rw-r--r--assets/mus/minigames/slots/slots_loop.mp3bin0 -> 28425 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_big_win.oggbin0 -> 171531 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_fail.oggbin0 -> 20109 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_lock.oggbin0 -> 10094 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_medium_win.oggbin0 -> 45149 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_small_win.oggbin0 -> 72343 bytes
-rw-r--r--assets/sfx/minigames/slots/slots_start.oggbin0 -> 28333 bytes
-rw-r--r--assets/sprites/gui/ui.skin8
-rw-r--r--assets/sprites/minigames/slots/arbuz.pngbin0 -> 22178 bytes
-rw-r--r--assets/sprites/minigames/slots/background.pngbin0 -> 114221 bytes
-rw-r--r--assets/sprites/minigames/slots/buter.pngbin0 -> 22277 bytes
-rw-r--r--assets/sprites/minigames/slots/corn.pngbin0 -> 21399 bytes
-rw-r--r--assets/sprites/minigames/slots/icecream.pngbin0 -> 21388 bytes
-rw-r--r--assets/sprites/minigames/slots/kebab.pngbin0 -> 20287 bytes
-rw-r--r--assets/sprites/minigames/slots/kochan.pngbin0 -> 22827 bytes
-rw-r--r--assets/sprites/minigames/slots/onions.pngbin0 -> 22142 bytes
-rw-r--r--assets/sprites/minigames/slots/treat.pngbin0 -> 21980 bytes
-rw-r--r--core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt407
-rw-r--r--core/src/kz/ilotterytea/maxon/screens/game/GameScreen.java8
21 files changed, 434 insertions, 1 deletions
diff --git a/assets/i18n/en_us.json b/assets/i18n/en_us.json
index d318c97..d685e21 100644
--- a/assets/i18n/en_us.json
+++ b/assets/i18n/en_us.json
@@ -47,6 +47,12 @@
"gifts.points": "[ORANGE]{WAVE=1.0;1.0;0.5}+%s Points{ENDWAVE}{CLEARCOLOR}",
"gifts.new_pet": "{RAINBOW}{WAVE=1.0;1.0;0.5}New pet! (%s){ENDWAVE}{ENDRAINBOW}",
+ "minigame.slots.nothing": "YOU WON NOTHINGG",
+ "minigame.slots.prize": "YOU WON %s P$",
+ "minigame.slots.bet": "BET",
+ "minigame.slots.spin_button": "SPIN",
+ "minigame.slots.exit_button": " X ",
+
"game.inventory.title": "Inventory",
"pet.bror.name": "The Suspicious and Sleepy Bro",
diff --git a/assets/i18n/ru_ru.json b/assets/i18n/ru_ru.json
index 1912382..8cf68b0 100644
--- a/assets/i18n/ru_ru.json
+++ b/assets/i18n/ru_ru.json
@@ -40,6 +40,12 @@
"game.multiplier": "%s/жмяк",
"game.newPoint": "{SHAKE}{RAINBOW}+%s{ENDRAINBOW}{ENDSHAKE}",
+ "minigame.slots.nothing": "ТЫ НИЧЕГО НЕ ВЫИГРАЛ",
+ "minigame.slots.prize": "ТЫ ВЫИГРАЛ %s P$",
+ "minigame.slots.bet": "СТАВКА",
+ "minigame.slots.spin_button": "КРУТАНУТЬ",
+ "minigame.slots.exit_button": " X ",
+
"game.inventory.title": "Инвентарь",
"dialogs.not_enough_points": "Недостаточно поинтов!",
diff --git a/assets/mus/minigames/slots/slots_loop.mp3 b/assets/mus/minigames/slots/slots_loop.mp3
new file mode 100644
index 0000000..be8f331
--- /dev/null
+++ b/assets/mus/minigames/slots/slots_loop.mp3
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_big_win.ogg b/assets/sfx/minigames/slots/slots_big_win.ogg
new file mode 100644
index 0000000..e42a6b9
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_big_win.ogg
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_fail.ogg b/assets/sfx/minigames/slots/slots_fail.ogg
new file mode 100644
index 0000000..0081a02
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_fail.ogg
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_lock.ogg b/assets/sfx/minigames/slots/slots_lock.ogg
new file mode 100644
index 0000000..faa743c
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_lock.ogg
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_medium_win.ogg b/assets/sfx/minigames/slots/slots_medium_win.ogg
new file mode 100644
index 0000000..f2031ad
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_medium_win.ogg
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_small_win.ogg b/assets/sfx/minigames/slots/slots_small_win.ogg
new file mode 100644
index 0000000..3bbf64d
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_small_win.ogg
Binary files differ
diff --git a/assets/sfx/minigames/slots/slots_start.ogg b/assets/sfx/minigames/slots/slots_start.ogg
new file mode 100644
index 0000000..54e45fd
--- /dev/null
+++ b/assets/sfx/minigames/slots/slots_start.ogg
Binary files differ
diff --git a/assets/sprites/gui/ui.skin b/assets/sprites/gui/ui.skin
index 4a1bd53..04598a4 100644
--- a/assets/sprites/gui/ui.skin
+++ b/assets/sprites/gui/ui.skin
@@ -45,6 +45,10 @@
tooltip: {
file: ../../fnt/FontText.fnt,
scaledSize: 19
+ },
+ slots: {
+ file: ../../fnt/FontText.fnt,
+ scaledSize: 16
}
},
com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: {
@@ -85,6 +89,10 @@
store_item_price_disabled: {
font: store_item_price,
fontColor: store_item_price_disabled
+ },
+ slots: {
+ font: slots,
+ fontColor: white
}
},
com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: {
diff --git a/assets/sprites/minigames/slots/arbuz.png b/assets/sprites/minigames/slots/arbuz.png
new file mode 100644
index 0000000..b8616ed
--- /dev/null
+++ b/assets/sprites/minigames/slots/arbuz.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/background.png b/assets/sprites/minigames/slots/background.png
new file mode 100644
index 0000000..7d22fe7
--- /dev/null
+++ b/assets/sprites/minigames/slots/background.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/buter.png b/assets/sprites/minigames/slots/buter.png
new file mode 100644
index 0000000..c6c789a
--- /dev/null
+++ b/assets/sprites/minigames/slots/buter.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/corn.png b/assets/sprites/minigames/slots/corn.png
new file mode 100644
index 0000000..60e1195
--- /dev/null
+++ b/assets/sprites/minigames/slots/corn.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/icecream.png b/assets/sprites/minigames/slots/icecream.png
new file mode 100644
index 0000000..83e93c8
--- /dev/null
+++ b/assets/sprites/minigames/slots/icecream.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/kebab.png b/assets/sprites/minigames/slots/kebab.png
new file mode 100644
index 0000000..696514b
--- /dev/null
+++ b/assets/sprites/minigames/slots/kebab.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/kochan.png b/assets/sprites/minigames/slots/kochan.png
new file mode 100644
index 0000000..371770c
--- /dev/null
+++ b/assets/sprites/minigames/slots/kochan.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/onions.png b/assets/sprites/minigames/slots/onions.png
new file mode 100644
index 0000000..c05e633
--- /dev/null
+++ b/assets/sprites/minigames/slots/onions.png
Binary files differ
diff --git a/assets/sprites/minigames/slots/treat.png b/assets/sprites/minigames/slots/treat.png
new file mode 100644
index 0000000..66a37a0
--- /dev/null
+++ b/assets/sprites/minigames/slots/treat.png
Binary files differ
diff --git a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt
new file mode 100644
index 0000000..863f295
--- /dev/null
+++ b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt
@@ -0,0 +1,407 @@
+package kz.ilotterytea.maxon.screens
+
+import com.badlogic.gdx.Gdx
+import com.badlogic.gdx.Input
+import com.badlogic.gdx.InputMultiplexer
+import com.badlogic.gdx.InputProcessor
+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.Image
+import com.badlogic.gdx.scenes.scene2d.ui.Label
+import com.badlogic.gdx.scenes.scene2d.ui.Skin
+import com.badlogic.gdx.scenes.scene2d.ui.Stack
+import com.badlogic.gdx.scenes.scene2d.ui.Table
+import com.badlogic.gdx.scenes.scene2d.ui.TextButton
+import com.badlogic.gdx.scenes.scene2d.ui.TextField
+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.player.Savegame
+import kz.ilotterytea.maxon.screens.game.GameScreen
+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))
+
+class SlotsMinigameScreen : Screen {
+ private val savegame = Savegame.getInstance()
+
+ private val game = MaxonGame.getInstance()
+ private val stage = Stage(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 finished = false
+ 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")
+
+ 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)
+
+ stage.addActor(table)
+
+ // Background
+ val background = Image(game.assetManager.get("sprites/minigames/slots/background.png", Texture::class.java))
+ background.zIndex = 2
+
+ table.add(background)
+
+ // Buttons
+ spinButton = TextButton(game.locale.TranslatableText("minigame.slots.spin_button"), skin)
+ 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()
+ }
+ })
+ stage.addActor(spinButton)
+
+ exitButton = TextButton(game.locale.TranslatableText("minigame.slots.exit_button"), skin)
+ 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()
+ }
+ })
+
+ stage.addActor(exitButton)
+
+ // Labels
+ prizeLabel = Label("", skin, "slots")
+ prizeLabel?.setAlignment(Align.center)
+ prizeLabel?.setPosition(stage.width / 2f - 180f, stage.height / 2f + 80f)
+ stage.addActor(prizeLabel)
+
+ 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)
+ stage.addActor(moneyIcon)
+
+ moneyLabel = Label(NumberFormatter.format(savegame.money.toLong()), skin, "slots")
+ moneyLabel?.setAlignment(Align.right)
+ moneyLabel?.setPosition(stage.width / 2f, stage.height / 2f - 180f)
+ stage.addActor(moneyLabel)
+
+ val stakeLabel = Label(game.locale.TranslatableText("minigame.slots.bet"), skin, "slots")
+ stakeLabel.setAlignment(Align.center)
+ stakeLabel.setPosition(stage.width / 2f - 40f, stage.height / 2f - 100f)
+ stage.addActor(stakeLabel)
+
+ stakeField = TextField("", skin)
+ 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)
+
+ stage.addActor(stakeField)
+
+ // Slot columns
+ columns.x = 62f
+ columns.y = stage.height / 2f
+ columns.width = 424f
+ stage.addActor(columns)
+
+ 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()
+
+ lockedColumns += 1
+
+ if (lockedColumns > 1) {
+ finish()
+ }
+ }
+ }
+
+ tasks.add(Pair(lockColumnTask, 2f))
+
+ disableSlotMachineIfNoStake()
+
+ audioLoop.isLooping = true
+
+ Gdx.input.inputProcessor = stage
+ }
+
+ override fun render(delta: Float) {
+ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT)
+ Gdx.gl.glClearColor(0f, 0f, 0f, 1f)
+
+ stage.act(delta)
+ stage.draw()
+ }
+
+ 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()
+
+ for (x in array) {
+ columnSlots.add(x)
+ columns.add(SlotImage(x, game.assetManager))
+ .size(100f, 100f)
+ .expandX()
+ }
+ }
+
+
+ private fun finish() {
+ if (audioLoop.isPlaying) audioLoop.stop()
+
+ finished = true
+ stakeField?.isDisabled = false
+ exitButton?.isDisabled = false
+ spinButton?.isDisabled = false
+
+ for (x in tasks) {
+ x.first.cancel()
+ }
+
+ giveReward()
+ updateLabels()
+ disableSlotMachineIfNoStake()
+ }
+
+ private fun restart() {
+ if (game.prefs.getBoolean("music", true)) audioLoop.play()
+
+ val sound = game.assetManager.get<Sound>("sfx/minigames/slots/slots_start.ogg")
+ sound.play()
+
+ prizeLabel?.setText("")
+
+ exitButton?.isDisabled = true
+ spinButton?.isDisabled = true
+ stakeField?.isDisabled = true
+
+ loseSlot = Slot.values()[Random.nextInt(0,3)]
+ finished = false
+ 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)
+
+ if (!same) {
+ loseStreak++
+ savegame.money -= stake
+ return
+ }
+
+ prize = stake * first.multiplier
+ savegame.money += prize
+ }
+
+ private fun updateLabels() {
+ val prizeText = if (prize == 0.0) {
+ game.locale.TranslatableText("minigame.slots.nothing")
+ } else {
+ game.locale.FormattedText("minigame.slots.prize", NumberFormatter.format(prize.toLong()))
+ }
+
+ prizeLabel?.setText(prizeText)
+
+ if (stake.toLong() > savegame.money.toLong()) {
+ stake = savegame.money
+
+ val stakeText = if (savegame.money.roundToInt() <= 0) {
+ "---"
+ } else {
+ NumberFormatter.format(savegame.money.toLong())
+ }
+
+ stakeField?.text = stakeText
+ }
+
+ moneyLabel?.setText(NumberFormatter.format(savegame.money.roundToLong()))
+ }
+
+ 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()
+ }
+
+ override fun resize(width: Int, height: Int) {
+ stage.viewport.update(width, height, true)
+ }
+
+ override fun pause() {
+ dispose()
+ }
+
+ override fun resume() {
+ show()
+ }
+
+ override fun hide() {
+ dispose()
+ }
+
+ override fun dispose() {
+ for (x in tasks) {
+ x.first.cancel()
+ }
+
+ tasks.clear()
+ stage.dispose()
+ audioLoop.stop()
+ }
+} \ No newline at end of file
diff --git a/core/src/kz/ilotterytea/maxon/screens/game/GameScreen.java b/core/src/kz/ilotterytea/maxon/screens/game/GameScreen.java
index b5f99be..c02226d 100644
--- a/core/src/kz/ilotterytea/maxon/screens/game/GameScreen.java
+++ b/core/src/kz/ilotterytea/maxon/screens/game/GameScreen.java
@@ -31,6 +31,7 @@ import kz.ilotterytea.maxon.player.MaxonItem;
import kz.ilotterytea.maxon.player.MaxonItemRegister;
import kz.ilotterytea.maxon.player.Savegame;
import kz.ilotterytea.maxon.screens.MenuScreen;
+import kz.ilotterytea.maxon.screens.SlotsMinigameScreen;
import kz.ilotterytea.maxon.screens.game.shop.ShopUI;
import kz.ilotterytea.maxon.ui.*;
import kz.ilotterytea.maxon.ui.game.QuickActionsTable;
@@ -99,7 +100,7 @@ public class GameScreen implements Screen, InputProcessor {
decalBatch = new DecalBatch(new CameraGroupStrategy(camera));
decals = new ArrayList<>();
- TextureRegion[] playerTextureRegions = SpriteUtils.splitToTextureRegions(game.assetManager.get("sprites/sheet/loadingCircle.png", Texture.class), 112, 112, 10, 5);
+ ArrayList<TextureRegion> playerTextureRegions = SpriteUtils.splitToTextureRegions(game.assetManager.get("sprites/sheet/loadingCircle.png", Texture.class), 112, 112, 10, 5);
decalPlayer = new DecalPlayer(savegame, playerTextureRegions);
decals.add(decalPlayer.getDecal());
@@ -320,6 +321,11 @@ public class GameScreen implements Screen, InputProcessor {
@Override
public boolean keyDown(int keycode) {
+ if (Gdx.input.isKeyPressed(Input.Keys.K)) {
+ game.setScreen(new SlotsMinigameScreen());
+ dispose();
+ }
+
if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
savegame.setElapsedTime((System.currentTimeMillis() - playTimestamp) + savegame.getElapsedTime());
savegame.save();