diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java index f9c967c..f9a4e0b 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java @@ -27,6 +27,7 @@ import pp.monopoly.client.gui.popups.Gulag; import pp.monopoly.client.gui.popups.GulagInfo; import pp.monopoly.client.gui.popups.LooserPopUp; import pp.monopoly.client.gui.popups.NoMoneyWarning; +import pp.monopoly.client.gui.popups.ReceivedRent; import pp.monopoly.client.gui.popups.RejectTrade; import pp.monopoly.client.gui.popups.Rent; import pp.monopoly.client.gui.popups.TimeOut; @@ -438,7 +439,9 @@ public class TestWorld implements GameEventListener { new AcceptTrade(app, (TradeReply) event.message()).open(); } else if (event.msg().equals("tradeneg")) { new RejectTrade(app, (TradeReply) event.message()).open(); - } + } else if (event.msg().equals("ReceivedRent")) { + new ReceivedRent(app, ( (NotificationMessage) event.message()).getRentOwner(), ( (NotificationMessage) event.message()).getRentAmount() ).open(); + } } private Vector3f calculateBuildingPosition(int fieldID) { diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/popups/ReceivedRent.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/popups/ReceivedRent.java new file mode 100644 index 0000000..83e8784 --- /dev/null +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/popups/ReceivedRent.java @@ -0,0 +1,167 @@ +package pp.monopoly.client.gui.popups; + +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.simsilica.lemur.Button; +import com.simsilica.lemur.Container; +import com.simsilica.lemur.Label; +import com.simsilica.lemur.component.QuadBackgroundComponent; +import com.simsilica.lemur.style.ElementId; +import pp.dialog.Dialog; +import pp.monopoly.client.MonopolyApp; +import pp.monopoly.notification.Sound; + +/** + * Rent is a popup that is triggered when a player lands on a property owned by another player + * and needs to pay rent in the Monopoly application. + *

+ * Displays the rent amount and the recipient player's name, with an option to confirm the payment. + *

+ */ +public class ReceivedRent extends Dialog { + /** Reference to the Monopoly application instance. */ + private final MonopolyApp app; + + /** Semi-transparent overlay background for the popup. */ + private final Geometry overlayBackground; + + /** Main container for the rent information and action. */ + private final Container rentContainer; + + /** Background container providing a border for the rent popup. */ + private final Container backgroundContainer; + + /** + * Constructs the Rent popup displaying the rent amount and recipient player. + * + * @param app the Monopoly application instance + * @param playerName the name of the player to whom the rent is owed + * @param amount the amount of rent to be paid + */ + public ReceivedRent(MonopolyApp app, String playerName, int amount) { + super(app.getDialogManager()); + this.app = app; + + // Create the overlay + overlayBackground = createOverlayBackground(); + app.getGuiNode().attachChild(overlayBackground); + + // Create and position the background container + backgroundContainer = createBackgroundContainer(); + app.getGuiNode().attachChild(backgroundContainer); + + // Create and position the rent container + rentContainer = createRentContainer(playerName, amount); + app.getGuiNode().attachChild(rentContainer); + + centerContainers(); + } + + /** + * Creates a semi-transparent overlay background. + * + * @return the overlay geometry + */ + private Geometry createOverlayBackground() { + Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); + Geometry overlay = new Geometry("Overlay", quad); + Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black + material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + overlay.setMaterial(material); + overlay.setLocalTranslation(0, 0, 0); + return overlay; + } + + /** + * Creates the background container with styling. + * + * @return the styled background container + */ + private Container createBackgroundContainer() { + Container container = new Container(); + container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background + return container; + } + + /** + * Creates the main rent container with title, text, and button. + * + * @param playerName the name of the player to whom the rent is owed + * @param amount the rent amount + * @return the rent container + */ + private Container createRentContainer(String playerName, int amount) { + Container container = new Container(); + container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray)); + container.setPreferredSize(new Vector3f(550, 250, 10)); + + // Title + Label title = container.addChild(new Label("Miete!", new ElementId("warning-title"))); + title.setFontSize(48); + title.setColor(ColorRGBA.Black); + + // Rent message + Container textContainer = container.addChild(new Container()); + textContainer.addChild(new Label("Du bekommst von Spieler " + playerName + " " + amount + " EUR Miete", + new ElementId("label-Text"))); + textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); + textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0)); + + // Payment button + Button payButton = container.addChild(new Button("Bestätigen", new ElementId("button"))); + payButton.setFontSize(32); + payButton.addClickCommands(s -> ifTopDialog( () -> { + app.getGameLogic().playSound(Sound.BUTTON); + close(); + + })); + + return container; + } + + /** + * Centers the rent and background containers on the screen. + */ + private void centerContainers() { + float padding = 10; + + // Center rent container + rentContainer.setLocalTranslation( + (app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2, + (app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2, + 8 + ); + + // Center background container with padding + backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0)); + backgroundContainer.setLocalTranslation( + (app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2, + (app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2, + 7 + ); + } + + /** + * Closes the popup and removes GUI elements. + */ + @Override + public void close() { + app.getGuiNode().detachChild(rentContainer); + app.getGuiNode().detachChild(backgroundContainer); + app.getGuiNode().detachChild(overlayBackground); + super.close(); + } + + /** + * Handles the escape action to close the dialog. + */ + @Override + public void escape() { + close(); + } +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java index 261a251..7507caf 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java @@ -352,6 +352,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker { notifyListeners(new PopUpEvent("jailpay", msg)); } else if (msg.getKeyWord().equals("jailtryagain")) { notifyListeners(new PopUpEvent("jailtryagain", msg)); + } else if(msg.getKeyWord().equals("ReceivedRent")) { + notifyListeners(new PopUpEvent("ReceivedRent", msg)); } } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java index e55b1c6..95f99b1 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java @@ -331,6 +331,13 @@ public class Player implements FieldVisitor{ state.useJailCard(); } + private void sendRentNotification(String keyword, Player player, int amount) { + NotificationMessage msg = new NotificationMessage(keyword); + msg.setRentAmount(amount); + msg.setRentOwnerId(player.getName()); + getHandler().getLogic().send(player, msg); + } + @Override public Void visit(BuildingProperty field) { if(field.getOwner() == null) { @@ -340,10 +347,8 @@ public class Player implements FieldVisitor{ int rent = field.calcRent(); field.getOwner().earnMoney(rent); pay(rent); - NotificationMessage msg = new NotificationMessage("rent"); - msg.setRentAmount(rent); - msg.setRentOwnerId(field.getOwner().getName()); - getHandler().getLogic().send(this, msg); + sendRentNotification("rent", field.getOwner(), rent); + sendRentNotification("ReceivedRent", this, rent); } return null; } @@ -360,10 +365,8 @@ public class Player implements FieldVisitor{ int rent = rollResult.calcTotal()*factor; field.getOwner().earnMoney(rent); pay(rent); - NotificationMessage msg = new NotificationMessage("rent"); - msg.setRentAmount(rent); - msg.setRentOwnerId(field.getOwner().getName()); - getHandler().getLogic().send(this, msg); + sendRentNotification("rent", field.getOwner(), rent); + sendRentNotification("ReceivedRent", this, rent); } return null; } @@ -377,10 +380,8 @@ public class Player implements FieldVisitor{ field.getOwner().earnMoney(rent); pay(rent); - NotificationMessage msg = new NotificationMessage("rent"); - msg.setRentAmount(rent); - msg.setRentOwnerId(field.getOwner().getName()); - getHandler().getLogic().send(this, msg); + sendRentNotification("rent", field.getOwner(), rent); + sendRentNotification("ReceivedRent", this, rent); } return null; }