Skip to content

Commit

Permalink
Add a delay between automatic turn actions
Browse files Browse the repository at this point in the history
  • Loading branch information
haykam821 committed Nov 21, 2024
1 parent 6ac4921 commit 67a4fbf
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 73 deletions.
1 change: 1 addition & 0 deletions src/main/java/io/github/haykam821/lastcard/card/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public final Text getFullName() {

public final boolean canPlay(AbstractPlayerEntry player) {
if (!player.hasTurn()) return false;
if (player.getPhase().getTurnManager().getTurnAction() != null) return false;

CardDeck deck = player.getPhase().getDeck();

Expand Down
21 changes: 2 additions & 19 deletions src/main/java/io/github/haykam821/lastcard/card/DrawCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import io.github.haykam821.lastcard.card.color.CardColor;
import io.github.haykam821.lastcard.card.color.ColorSelector;
import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;
import net.minecraft.text.Text;
import io.github.haykam821.lastcard.turn.action.DrawTurnAction;

public abstract class DrawCard extends SymbolCard {
private final int value;
Expand All @@ -28,22 +27,6 @@ public boolean isMatching(Card card, CardColor color) {
@Override
public void play(AbstractPlayerEntry player) {
super.play(player);

LastCardActivePhase phase = player.getPhase();
AbstractPlayerEntry drawPlayer = phase.getPlayerEntry(phase.getTurnManager().getNextTurnIndex(false));

for (int index = 0; index < this.value; index++) {
drawPlayer.draw();
}

this.sendDrawMessage(phase, drawPlayer);
phase.getTurnManager().skipNextTurn();
}

private void sendDrawMessage(LastCardActivePhase phase, AbstractPlayerEntry player) {
Text cardDrewMessage = player.getCardDrewMessage(this.value);
Text cardDrewManyYouMessage = player.getCardDrewManyYouMessage(this.value);

phase.sendMessageWithException(cardDrewMessage, player, cardDrewManyYouMessage);
player.getPhase().getTurnManager().setNextTurnAction(new DrawTurnAction(this.value));
}
}
22 changes: 2 additions & 20 deletions src/main/java/io/github/haykam821/lastcard/card/SkipCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import io.github.haykam821.lastcard.card.color.CardColor;
import io.github.haykam821.lastcard.card.color.ColorSelector;
import io.github.haykam821.lastcard.card.display.CardTemplates;
import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;
import io.github.haykam821.lastcard.turn.action.SkipTurnAction;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;

public class SkipCard extends SymbolCard {
public SkipCard(ColorSelector selector) {
Expand All @@ -32,24 +31,7 @@ public boolean isMatching(Card card, CardColor color) {
@Override
public void play(AbstractPlayerEntry player) {
super.play(player);

this.sendTurnSkippedMessage(player.getPhase());
player.getPhase().getTurnManager().skipNextTurn();
}

private void sendTurnSkippedMessage(LastCardActivePhase phase) {
int skippedIndex = phase.getTurnManager().getNextTurnIndex(false);
AbstractPlayerEntry skippedPlayer = phase.getPlayerEntry(skippedIndex);

phase.sendMessageWithException(this.getTurnSkippedMessage(skippedPlayer), skippedPlayer, this.getTurnSkippedYouMessage());
}

private Text getTurnSkippedMessage(AbstractPlayerEntry player) {
return Text.translatable("text.lastcard.turn.skipped", player.getName()).formatted(Formatting.GOLD);
}

private Text getTurnSkippedYouMessage() {
return Text.translatable("text.lastcard.turn.skipped.you").formatted(Formatting.GOLD);
player.getPhase().getTurnManager().setNextTurnAction(SkipTurnAction.INSTANCE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.github.haykam821.lastcard.game.map.Chair;
import io.github.haykam821.lastcard.game.map.StatusHologram;
import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.turn.action.TurnAction;
import net.minecraft.server.network.ServerPlayerEntity;
import xyz.nucleoid.map_templates.TemplateRegion;

Expand Down Expand Up @@ -161,7 +162,10 @@ public final void markDirtyDisplays() {
this.dirtyDisplays = true;
}

public void performVirtualAction() {
return;
/**
* {@return a behavior that this player should perform during their turn instead of normal selection}
*/
public TurnAction getTurnAction() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package io.github.haykam821.lastcard.game.player;

import org.apache.commons.lang3.RandomStringUtils;
import java.util.UUID;

import io.github.haykam821.lastcard.card.Card;
import io.github.haykam821.lastcard.card.color.ColorSelector;
import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.turn.action.TurnAction;
import io.github.haykam821.lastcard.turn.action.VirtualTurnAction;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.NameGenerator;
import xyz.nucleoid.map_templates.TemplateRegion;

public class VirtualPlayerEntry extends AbstractPlayerEntry {
private final String key = RandomStringUtils.randomAlphabetic(6);
private final String key = NameGenerator.name(UUID.randomUUID());
private final Text name = Text.literal(this.key).formatted(Formatting.GRAY);

public VirtualPlayerEntry(LastCardActivePhase phase, TemplateRegion chair, TemplateRegion publicDisplay) {
Expand Down Expand Up @@ -41,19 +42,8 @@ public ItemStack createHeadStack() {
}

@Override
public void performVirtualAction() {
// Play the first playable card
for (Card card : this.getCards()) {
if (card.canPlay(this)) {
ColorSelector selector = card.getSelector();
this.playCard(card, selector.select(0, 0));

return;
}
}

// If no cards are playable, draw
this.drawForTurn();
public TurnAction getTurnAction() {
return VirtualTurnAction.INSTANCE;
}

@Override
Expand Down
43 changes: 28 additions & 15 deletions src/main/java/io/github/haykam821/lastcard/turn/TurnManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.haykam821.lastcard.card.display.CardDisplay;
import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;
import io.github.haykam821.lastcard.turn.action.TurnAction;
import net.minecraft.SharedConstants;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.server.world.ServerWorld;
Expand All @@ -21,15 +22,15 @@ public class TurnManager {
private static final double PARTICLE_SPEED = 1 / 15d;
private static final int PARTICLE_UPDATE_RATE = 1;

private static final int VIRTUAL_ACTION_TURN_TICKS = SharedConstants.TICKS_PER_SECOND;
private static final int TURN_ACTION_TICKS = SharedConstants.TICKS_PER_SECOND;

private final LastCardActivePhase phase;

private final CardDisplay privatePileDisplay;
private final CardDisplay publicPileDisplay;

private AbstractPlayerEntry turn;
private boolean skipNextTurn = false;
private TurnAction action;
private TurnDirection direction = TurnDirection.CLOCKWISE;
private int turnTicks = 0;

Expand All @@ -56,21 +57,22 @@ public void setTurn(AbstractPlayerEntry turn) {
this.turn = turn;
}

public int getNextTurnIndex(boolean skipNextTurn) {
int offset = this.direction.multiply(skipNextTurn && this.skipNextTurn ? 2 : 1);

return this.phase.getPlayers().indexOf(this.turn) + offset;
private int getNextTurnIndex() {
return this.phase.getPlayers().indexOf(this.turn) + this.direction.multiply(1);
}

public void cycleTurn() {
if (this.phase.getPlayers().isEmpty()) return;

AbstractPlayerEntry oldTurn = this.turn;

this.turn = this.phase.getPlayerEntry(this.getNextTurnIndex(true));
this.skipNextTurn = false;
this.turn = this.phase.getPlayerEntry(this.getNextTurnIndex());
this.turnTicks = 0;

if (this.action == null) {
this.action = this.turn.getTurnAction();
}

if (oldTurn != this.turn) {
this.sendNextTurnEffects();

Expand All @@ -88,26 +90,37 @@ public void cycleTurn() {
this.phase.updatePileDisplay();
}

public void skipNextTurn() {
this.skipNextTurn = true;
public TurnAction getTurnAction() {
return this.action;
}

/**
* Sets a turn action that should supersede the next player's {@linkplain AbstractPlayerEntry#getTurnAction() default turn action}.
* @param action the turn action that should be set for the next turn
*/
public void setNextTurnAction(TurnAction action) {
this.action = action;
}

public TurnDirection reverseDirection() {
return this.direction = this.direction.getOpposite();
}

public void sendNextTurnEffects() {
if (this.turn != null) {
if (this.turn != null && (this.action == null || this.action.hasNextTurnEffects())) {
this.phase.sendMessage(this.turn.getNextTurnMessage());
TurnSounds.playTurnSounds(this.turn.getPlayer());
}
}

private void tickVirtualAction() {
private void tickAction() {
this.turnTicks += 1;

if (this.turnTicks == VIRTUAL_ACTION_TURN_TICKS && this.turn != null) {
this.turn.performVirtualAction();
if (this.turnTicks == TURN_ACTION_TICKS && this.turn != null && this.action != null) {
TurnAction action = this.action;
this.action = null;

action.run(turn);
}
}

Expand All @@ -134,7 +147,7 @@ private void tickParticles() {

public void tick() {
if (!this.phase.isGameEnding()) {
this.tickVirtualAction();
this.tickAction();
}

this.tickParticles();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.haykam821.lastcard.turn.action;

import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;
import net.minecraft.text.Text;

public class DrawTurnAction implements TurnAction {
private final int value;

public DrawTurnAction(int value) {
this.value = value;
}

@Override
public void run(AbstractPlayerEntry player) {
LastCardActivePhase phase = player.getPhase();

for (int index = 0; index < this.value; index++) {
player.draw();
}

this.sendDrawMessage(phase, player);
phase.getTurnManager().cycleTurn();
}

private void sendDrawMessage(LastCardActivePhase phase, AbstractPlayerEntry player) {
Text cardDrewMessage = player.getCardDrewMessage(this.value);
Text cardDrewManyYouMessage = player.getCardDrewManyYouMessage(this.value);

phase.sendMessageWithException(cardDrewMessage, player, cardDrewManyYouMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.github.haykam821.lastcard.turn.action;

import io.github.haykam821.lastcard.game.phase.LastCardActivePhase;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;

public class SkipTurnAction implements TurnAction {
public static final TurnAction INSTANCE = new SkipTurnAction();

private SkipTurnAction() {
return;
}

@Override
public void run(AbstractPlayerEntry player) {
LastCardActivePhase phase = player.getPhase();

phase.sendMessageWithException(this.getTurnSkippedMessage(player), player, this.getTurnSkippedYouMessage());
phase.getTurnManager().cycleTurn();
}

private Text getTurnSkippedMessage(AbstractPlayerEntry player) {
return Text.translatable("text.lastcard.turn.skipped", player.getName()).formatted(Formatting.GOLD);
}

private Text getTurnSkippedYouMessage() {
return Text.translatable("text.lastcard.turn.skipped.you").formatted(Formatting.GOLD);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.github.haykam821.lastcard.turn.action;

import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;

public interface TurnAction {
public void run(AbstractPlayerEntry player);

public default boolean hasNextTurnEffects() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.github.haykam821.lastcard.turn.action;

import io.github.haykam821.lastcard.card.Card;
import io.github.haykam821.lastcard.card.color.ColorSelector;
import io.github.haykam821.lastcard.game.player.AbstractPlayerEntry;

public class VirtualTurnAction implements TurnAction {
public static final TurnAction INSTANCE = new VirtualTurnAction();

private VirtualTurnAction() {
return;
}

@Override
public void run(AbstractPlayerEntry player) {
// Play the first playable card
for (Card card : player.getCards()) {
if (card.canPlay(player)) {
ColorSelector selector = card.getSelector();
player.playCard(card, selector.select(0, 0));

return;
}
}

// If no cards are playable, draw
player.drawForTurn();
}

@Override
public boolean hasNextTurnEffects() {
return true;
}
}

0 comments on commit 67a4fbf

Please sign in to comment.