move slot machine functionality to the blockentity
This commit is contained in:
@@ -157,7 +157,10 @@ public class SlotMachineScreen extends HandledScreen<SlotMachineScreenHandler> {
|
|||||||
|
|
||||||
int guiLeft = (width - backgroundWidth) / 2;
|
int guiLeft = (width - backgroundWidth) / 2;
|
||||||
int guiTop = (height - backgroundHeight) / 2;
|
int guiTop = (height - backgroundHeight) / 2;
|
||||||
|
if (handler.blockEntity.isHandleClicked(inventory.player)) {
|
||||||
|
handleClicked = true;
|
||||||
|
handleAnimTicks = 0;
|
||||||
|
}
|
||||||
// Handle animation
|
// Handle animation
|
||||||
if (handleClicked) {
|
if (handleClicked) {
|
||||||
handleAnimTicks++;
|
handleAnimTicks++;
|
||||||
|
|||||||
@@ -178,4 +178,16 @@ public class SlotMachineBlock extends Block implements BlockEntityProvider {
|
|||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(
|
||||||
|
World world,
|
||||||
|
BlockState state,
|
||||||
|
BlockEntityType<T> type) {
|
||||||
|
|
||||||
|
return type == Szar.SLOT_MACHINE_BLOCKENTITY
|
||||||
|
? (world1, pos, state1, blockEntity) ->
|
||||||
|
SlotMachineBlockEntity.tick(world1, pos, state1, (SlotMachineBlockEntity) blockEntity)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,14 @@ package dev.tggamesyt.szar;
|
|||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.SimpleInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||||
import net.minecraft.network.packet.Packet;
|
import net.minecraft.network.packet.Packet;
|
||||||
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
||||||
|
import net.minecraft.screen.ArrayPropertyDelegate;
|
||||||
|
import net.minecraft.screen.PropertyDelegate;
|
||||||
import net.minecraft.util.ItemScatterer;
|
import net.minecraft.util.ItemScatterer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
@@ -17,6 +20,18 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class SlotMachineBlockEntity extends BlockEntity {
|
public class SlotMachineBlockEntity extends BlockEntity {
|
||||||
|
|
||||||
|
// ===== TIMING CONFIG =====
|
||||||
|
public static final int PREPARE_TIME = 35;
|
||||||
|
public static final int FAST_SPIN_TIME = 35;
|
||||||
|
public static final int LOCK_INTERVAL = 8;
|
||||||
|
private static final int RESULT_VIEW_TIME = 80;
|
||||||
|
|
||||||
|
private static final int IDLE_SPEED = 20;
|
||||||
|
private static final int PREPARE_SPEED = 8;
|
||||||
|
private static final int FAST_SPEED = 1;
|
||||||
|
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
public final int[] currentSymbol = new int[3];
|
public final int[] currentSymbol = new int[3];
|
||||||
public final int[] finalSymbol = new int[3];
|
public final int[] finalSymbol = new int[3];
|
||||||
public static final int TOTAL_SYMBOLS = 7;
|
public static final int TOTAL_SYMBOLS = 7;
|
||||||
@@ -26,9 +41,15 @@ public class SlotMachineBlockEntity extends BlockEntity {
|
|||||||
private ItemStack currentBetStack = ItemStack.EMPTY;
|
private ItemStack currentBetStack = ItemStack.EMPTY;
|
||||||
private boolean forceWin = false;
|
private boolean forceWin = false;
|
||||||
private int winTier = 0; // 0 = fruit, 1 = golden apple small, 2 = golden apple jackpot
|
private int winTier = 0; // 0 = fruit, 1 = golden apple small, 2 = golden apple jackpot
|
||||||
|
private boolean isHandleClicked = false;
|
||||||
|
private PlayerEntity clickedplayer;
|
||||||
|
private int handleClickWaittime = 0;
|
||||||
|
|
||||||
|
final PropertyDelegate propertyDelegate;
|
||||||
|
|
||||||
public SlotMachineBlockEntity(BlockPos pos, BlockState state) {
|
public SlotMachineBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(Szar.SLOT_MACHINE_BLOCKENTITY, pos, state);
|
super(Szar.SLOT_MACHINE_BLOCKENTITY, pos, state);
|
||||||
|
this.propertyDelegate = new ArrayPropertyDelegate(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSymbols(int s0, int s1, int s2) {
|
public void setSymbols(int s0, int s1, int s2) {
|
||||||
@@ -105,6 +126,8 @@ public class SlotMachineBlockEntity extends BlockEntity {
|
|||||||
public boolean getForceWin() {return forceWin;}
|
public boolean getForceWin() {return forceWin;}
|
||||||
public void setwinTier(int winTier) {this.winTier = winTier;}
|
public void setwinTier(int winTier) {this.winTier = winTier;}
|
||||||
public int getwinTier() {return winTier;}
|
public int getwinTier() {return winTier;}
|
||||||
|
public boolean isHandleClicked(PlayerEntity player) {return clickedplayer != player ? isHandleClicked : false;}
|
||||||
|
public void setHandleClicked(boolean isHandleClicked, PlayerEntity player) {this.isHandleClicked = isHandleClicked; this.clickedplayer = player;}
|
||||||
|
|
||||||
void finishSpin() {
|
void finishSpin() {
|
||||||
if (getForceWin()) {
|
if (getForceWin()) {
|
||||||
@@ -129,4 +152,112 @@ public class SlotMachineBlockEntity extends BlockEntity {
|
|||||||
setcurrentBetAmount(0);
|
setcurrentBetAmount(0);
|
||||||
setcurrentBetStack(ItemStack.EMPTY);
|
setcurrentBetStack(ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
public static void tick(World world, BlockPos pos, BlockState state, SlotMachineBlockEntity blockEntity) {
|
||||||
|
if (world.isClient) return;
|
||||||
|
if (blockEntity.isHandleClicked) {
|
||||||
|
blockEntity.handleClickWaittime++;
|
||||||
|
}
|
||||||
|
if (blockEntity.handleClickWaittime >= 1) {
|
||||||
|
blockEntity.isHandleClicked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// old sendcontentupdates
|
||||||
|
if (!blockEntity.getSpinning()) {
|
||||||
|
if (blockEntity.getWorld().getTime() % IDLE_SPEED == 0) {
|
||||||
|
System.out.println("setting random symbols");
|
||||||
|
blockEntity.setSymbols(
|
||||||
|
blockEntity.random.nextInt(7),
|
||||||
|
blockEntity.random.nextInt(7),
|
||||||
|
blockEntity.random.nextInt(7)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockEntity.setspinTimer(blockEntity.getspinTimer() + 1);
|
||||||
|
|
||||||
|
int totalSpinDuration =
|
||||||
|
PREPARE_TIME +
|
||||||
|
FAST_SPIN_TIME +
|
||||||
|
LOCK_INTERVAL * 3 +
|
||||||
|
RESULT_VIEW_TIME;
|
||||||
|
|
||||||
|
int speed = switch (blockEntity.getspinTimer() < PREPARE_TIME ? 0 : blockEntity.getspinTimer() < PREPARE_TIME + FAST_SPIN_TIME ? 1 : 2) {
|
||||||
|
case 0 -> PREPARE_SPEED;
|
||||||
|
case 1 -> FAST_SPEED;
|
||||||
|
default -> FAST_SPEED;
|
||||||
|
};
|
||||||
|
|
||||||
|
boolean lock0 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL;
|
||||||
|
boolean lock1 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL * 2;
|
||||||
|
boolean lock2 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL * 3;
|
||||||
|
|
||||||
|
int reel0 = lock0 ? blockEntity.getFinalSymbol(0) : blockEntity.random.nextInt(7);
|
||||||
|
int reel1 = lock1 ? blockEntity.getFinalSymbol(1) : blockEntity.random.nextInt(7);
|
||||||
|
int reel2 = lock2 ? blockEntity.getFinalSymbol(2) : blockEntity.random.nextInt(7);
|
||||||
|
|
||||||
|
if (blockEntity.getspinTimer() % speed == 0) {
|
||||||
|
blockEntity.setSymbols(reel0, reel1, reel2);
|
||||||
|
}
|
||||||
|
if (blockEntity.getspinTimer() >= (totalSpinDuration - RESULT_VIEW_TIME + 15)) {
|
||||||
|
blockEntity.propertyDelegate.set(1, blockEntity.getForceWin() ? 1 : 0);
|
||||||
|
}
|
||||||
|
if (blockEntity.getspinTimer() >= totalSpinDuration) {
|
||||||
|
blockEntity.finishSpin();
|
||||||
|
blockEntity.setSpinning(false);
|
||||||
|
blockEntity.propertyDelegate.set(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onButtonClicked(PlayerEntity player, SlotMachineBlockEntity blockEntity, SimpleInventory betInventory) {
|
||||||
|
blockEntity.setHandleClicked(true, player);
|
||||||
|
ItemStack bet = betInventory.getStack(0);
|
||||||
|
if (bet.isEmpty()) return false;
|
||||||
|
|
||||||
|
blockEntity.setcurrentBetAmount(bet.getCount());
|
||||||
|
blockEntity.setcurrentBetStack(bet.copy());
|
||||||
|
betInventory.setStack(0, ItemStack.EMPTY);
|
||||||
|
|
||||||
|
// === Determine if this spin will definitely win (40%) ===
|
||||||
|
blockEntity.setForceWin(random.nextFloat() < 0.4f);
|
||||||
|
if (blockEntity.getForceWin()) {
|
||||||
|
float tierRoll = random.nextFloat();
|
||||||
|
if (tierRoll < 0.88f) blockEntity.setwinTier(0); // 88%
|
||||||
|
else if (tierRoll < 0.98f) blockEntity.setwinTier(1); // 10%
|
||||||
|
else blockEntity.setwinTier(2); // 2%
|
||||||
|
} else {
|
||||||
|
blockEntity.setwinTier(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Preselect final symbols based on forced win type ===
|
||||||
|
if (blockEntity.getForceWin()) {
|
||||||
|
switch (blockEntity.getwinTier()) {
|
||||||
|
case 0 -> { // fruit
|
||||||
|
int symbol = SlotSymbol.symbolToInt(SlotSymbol.rollFruit(random));
|
||||||
|
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
||||||
|
}
|
||||||
|
case 1 -> { // golden apple small
|
||||||
|
int symbol = SlotSymbol.symbolToInt(SlotSymbol.BELL);
|
||||||
|
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
||||||
|
}
|
||||||
|
case 2 -> { // jackpot
|
||||||
|
int symbol = SlotSymbol.symbolToInt(SlotSymbol.SEVEN);
|
||||||
|
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blockEntity.setFinalSymbols(SlotSymbol.symbolToInt(SlotSymbol.roll(random)), SlotSymbol.symbolToInt(SlotSymbol.roll(random)), SlotSymbol.symbolToInt(SlotSymbol.roll(random)));
|
||||||
|
|
||||||
|
if (blockEntity.getFinalSymbol(0) == blockEntity.getFinalSymbol(1) && blockEntity.getFinalSymbol(1) == blockEntity.getFinalSymbol(2)) {
|
||||||
|
blockEntity.setForceWin(true);
|
||||||
|
blockEntity.setwinTier(SlotSymbol.intToSymbol(blockEntity.getFinalSymbol(0)) == SlotSymbol.BELL ? 1 : SlotSymbol.intToSymbol(blockEntity.getFinalSymbol(0)) == SlotSymbol.SEVEN ? 2 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockEntity.setspinTimer(0);
|
||||||
|
blockEntity.setSpinning(true);
|
||||||
|
blockEntity.propertyDelegate.set(0, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,29 +16,19 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class SlotMachineScreenHandler extends ScreenHandler {
|
public class SlotMachineScreenHandler extends ScreenHandler {
|
||||||
|
|
||||||
// ===== TIMING CONFIG =====
|
|
||||||
public static final int PREPARE_TIME = 35;
|
|
||||||
public static final int FAST_SPIN_TIME = 35;
|
|
||||||
public static final int LOCK_INTERVAL = 8;
|
|
||||||
private static final int RESULT_VIEW_TIME = 80;
|
|
||||||
|
|
||||||
private static final int IDLE_SPEED = 20;
|
|
||||||
private static final int PREPARE_SPEED = 8;
|
|
||||||
private static final int FAST_SPEED = 1;
|
|
||||||
|
|
||||||
public final SlotMachineBlockEntity blockEntity;
|
public final SlotMachineBlockEntity blockEntity;
|
||||||
private final SimpleInventory betInventory = new SimpleInventory(1);
|
private final SimpleInventory betInventory = new SimpleInventory(1);
|
||||||
private final PlayerInventory playerInventory;
|
|
||||||
private final PropertyDelegate propertyDelegate;
|
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
|
|
||||||
public SlotMachineScreenHandler(int syncId, PlayerInventory playerInv, SlotMachineBlockEntity blockEntity) {
|
public SlotMachineScreenHandler(int syncId, PlayerInventory playerInv, SlotMachineBlockEntity blockEntity) {
|
||||||
super(Szar.SLOT_MACHINE_SCREEN_HANDLER_TYPE, syncId);
|
super(Szar.SLOT_MACHINE_SCREEN_HANDLER_TYPE, syncId);
|
||||||
this.playerInventory = playerInv;
|
|
||||||
this.blockEntity = blockEntity;
|
this.blockEntity = blockEntity;
|
||||||
|
|
||||||
this.propertyDelegate = new ArrayPropertyDelegate(2);
|
|
||||||
this.addProperties(propertyDelegate);
|
this.addProperties(blockEntity.propertyDelegate);
|
||||||
|
|
||||||
// Bet slot
|
// Bet slot
|
||||||
this.addSlot(new Slot(betInventory, 0, 44, 35));
|
this.addSlot(new Slot(betInventory, 0, 44, 35));
|
||||||
@@ -54,106 +44,14 @@ public class SlotMachineScreenHandler extends ScreenHandler {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onButtonClick(PlayerEntity player, int id) {
|
public boolean onButtonClick(PlayerEntity player, int id) {
|
||||||
if (id != 0 || blockEntity.getSpinning()) return false;
|
if (id != 0 || blockEntity.getSpinning()) return false;
|
||||||
|
return blockEntity.onButtonClicked(player, blockEntity, betInventory);
|
||||||
ItemStack bet = betInventory.getStack(0);
|
|
||||||
if (bet.isEmpty()) return false;
|
|
||||||
|
|
||||||
blockEntity.setcurrentBetAmount(bet.getCount());
|
|
||||||
blockEntity.setcurrentBetStack(bet.copy());
|
|
||||||
betInventory.setStack(0, ItemStack.EMPTY);
|
|
||||||
|
|
||||||
// === Determine if this spin will definitely win (40%) ===
|
|
||||||
blockEntity.setForceWin(random.nextFloat() < 0.4f);
|
|
||||||
if (blockEntity.getForceWin()) {
|
|
||||||
float tierRoll = random.nextFloat();
|
|
||||||
if (tierRoll < 0.88f) blockEntity.setwinTier(0); // 88%
|
|
||||||
else if (tierRoll < 0.98f) blockEntity.setwinTier(1); // 10%
|
|
||||||
else blockEntity.setwinTier(2); // 2%
|
|
||||||
} else {
|
|
||||||
blockEntity.setwinTier(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// === Preselect final symbols based on forced win type ===
|
|
||||||
if (blockEntity.getForceWin()) {
|
|
||||||
switch (blockEntity.getwinTier()) {
|
|
||||||
case 0 -> { // fruit
|
|
||||||
int symbol = SlotSymbol.symbolToInt(SlotSymbol.rollFruit(random));
|
|
||||||
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
|
||||||
}
|
|
||||||
case 1 -> { // golden apple small
|
|
||||||
int symbol = SlotSymbol.symbolToInt(SlotSymbol.BELL);
|
|
||||||
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
|
||||||
}
|
|
||||||
case 2 -> { // jackpot
|
|
||||||
int symbol = SlotSymbol.symbolToInt(SlotSymbol.SEVEN);
|
|
||||||
blockEntity.setFinalSymbols(symbol, symbol, symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
blockEntity.setFinalSymbols(SlotSymbol.symbolToInt(SlotSymbol.roll(random)), SlotSymbol.symbolToInt(SlotSymbol.roll(random)), SlotSymbol.symbolToInt(SlotSymbol.roll(random)));
|
|
||||||
|
|
||||||
if (blockEntity.getFinalSymbol(0) == blockEntity.getFinalSymbol(1) && blockEntity.getFinalSymbol(1) == blockEntity.getFinalSymbol(2)) {
|
|
||||||
blockEntity.setForceWin(true);
|
|
||||||
blockEntity.setwinTier(SlotSymbol.intToSymbol(blockEntity.getFinalSymbol(0)) == SlotSymbol.BELL ? 1 : SlotSymbol.intToSymbol(blockEntity.getFinalSymbol(0)) == SlotSymbol.SEVEN ? 2 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blockEntity.setspinTimer(0);
|
|
||||||
blockEntity.setSpinning(true);
|
|
||||||
propertyDelegate.set(0, 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
@Override
|
@Override
|
||||||
public void sendContentUpdates() {
|
public void sendContentUpdates() {
|
||||||
super.sendContentUpdates();
|
super.sendContentUpdates();
|
||||||
|
|
||||||
if (!blockEntity.getSpinning()) {
|
}*/
|
||||||
if (blockEntity.getWorld().getTime() % IDLE_SPEED == 0) {
|
|
||||||
blockEntity.setSymbols(
|
|
||||||
random.nextInt(7),
|
|
||||||
random.nextInt(7),
|
|
||||||
random.nextInt(7)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockEntity.setspinTimer(blockEntity.getspinTimer() + 1);
|
|
||||||
|
|
||||||
int totalSpinDuration =
|
|
||||||
PREPARE_TIME +
|
|
||||||
FAST_SPIN_TIME +
|
|
||||||
LOCK_INTERVAL * 3 +
|
|
||||||
RESULT_VIEW_TIME;
|
|
||||||
|
|
||||||
int speed = switch (blockEntity.getspinTimer() < PREPARE_TIME ? 0 : blockEntity.getspinTimer() < PREPARE_TIME + FAST_SPIN_TIME ? 1 : 2) {
|
|
||||||
case 0 -> PREPARE_SPEED;
|
|
||||||
case 1 -> FAST_SPEED;
|
|
||||||
default -> FAST_SPEED;
|
|
||||||
};
|
|
||||||
|
|
||||||
boolean lock0 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL;
|
|
||||||
boolean lock1 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL * 2;
|
|
||||||
boolean lock2 = blockEntity.getspinTimer() >= PREPARE_TIME + FAST_SPIN_TIME + LOCK_INTERVAL * 3;
|
|
||||||
|
|
||||||
int reel0 = lock0 ? blockEntity.getFinalSymbol(0) : random.nextInt(7);
|
|
||||||
int reel1 = lock1 ? blockEntity.getFinalSymbol(1) : random.nextInt(7);
|
|
||||||
int reel2 = lock2 ? blockEntity.getFinalSymbol(2) : random.nextInt(7);
|
|
||||||
|
|
||||||
if (blockEntity.getspinTimer() % speed == 0) {
|
|
||||||
blockEntity.setSymbols(reel0, reel1, reel2);
|
|
||||||
}
|
|
||||||
if (blockEntity.getspinTimer() >= (totalSpinDuration - RESULT_VIEW_TIME + 15)) {
|
|
||||||
propertyDelegate.set(1, blockEntity.getForceWin() ? 1 : 0);
|
|
||||||
}
|
|
||||||
if (blockEntity.getspinTimer() >= totalSpinDuration) {
|
|
||||||
blockEntity.finishSpin();
|
|
||||||
blockEntity.setSpinning(false);
|
|
||||||
propertyDelegate.set(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUse(PlayerEntity player) {
|
public boolean canUse(PlayerEntity player) {
|
||||||
@@ -194,6 +92,6 @@ public class SlotMachineScreenHandler extends ScreenHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDelegate getPropertyDelegate() {
|
public PropertyDelegate getPropertyDelegate() {
|
||||||
return propertyDelegate;
|
return blockEntity.propertyDelegate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user