send Trades

This commit is contained in:
Johannes Schmelz 2024-11-30 15:15:30 +01:00
parent 2c536f32cf
commit b681b13468
9 changed files with 147 additions and 122 deletions

View File

@ -6,6 +6,7 @@ import com.jme3.math.Vector3f;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.popups.BuyCard;
import pp.monopoly.client.gui.popups.ConfirmTrade;
import pp.monopoly.client.gui.popups.EventCardPopup;
import pp.monopoly.client.gui.popups.FoodFieldCard;
import pp.monopoly.client.gui.popups.GateFieldCard;
@ -150,6 +151,8 @@ public class TestWorld implements GameEventListener{
new LooserPopUp(app).open();
} else if(event.msg().equals("timeout")) {
new TimeOut(app).open();
} else if (event.msg().equals("tradeRequest")) {
new ConfirmTrade(app).open();
}
}

View File

@ -1,8 +1,5 @@
package pp.monopoly.client.gui;
import static java.lang.Math.min;
import com.jme3.app.Application;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
@ -15,13 +12,16 @@ import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList;
import com.simsilica.lemur.core.VersionedReference;
import com.simsilica.lemur.style.ElementId;
import com.simsilica.lemur.text.DocumentModel;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.server.Player;
import pp.monopoly.message.client.TradeOffer;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.fields.PropertyField;
import pp.monopoly.notification.Sound;
import java.util.HashSet;
import java.util.Set;
public class TradeMenu extends Dialog {
@ -29,15 +29,18 @@ public class TradeMenu extends Dialog {
private final TradeHandler tradeHandler;
private final Container mainContainer;
private Geometry background;
private Selector<String> leftBuildingSelector, leftSpecialCardSelector;
private Selector<String> rightBuildingSelector, rightSpecialCardSelector;
private TextField leftSelectionsField, rightSelectionsField;
private TextField leftCurrencyInput, rightCurrencyInput;
private VersionedReference<Set<Integer>> selectionRef; // Reference to track selector changes
private String valueSelected = ""; // To keep track of the last selected value
private String buildingSelected = "";
private String specialCardSelected = "";
private VersionedReference<Set<Integer>> leftBuildingRef, rightBuildingRef;
private VersionedReference<DocumentModel> leftCurrencyRef, rightCurrencyRef;
private VersionedReference<Set<Integer>> leftCardRef, rightCardRef;
private Set<String> rightselBuildings = new HashSet<>();
private Set<String> leftselBuildings = new HashSet<>();
private static final ColorRGBA TRANSLUCENT_WHITE = new ColorRGBA(1, 1, 1, 0.5f);
@ -51,6 +54,8 @@ public class TradeMenu extends Dialog {
mainContainer = createMainContainer();
app.getGuiNode().attachChild(mainContainer);
positionMainContainer();
initializeReferences();
}
private Container createMainContainer() {
@ -81,15 +86,17 @@ public class TradeMenu extends Dialog {
Container buttons = mainContent.addChild(new Container(new SpringGridLayout()));
Button cancel = new Button("Abbrechen");
cancel.addClickCommands(s-> ifTopDialog( () -> {
cancel.addClickCommands(s -> ifTopDialog(() -> {
close();
app.getGameLogic().playSound(Sound.BUTTON);
}));
Button trade = new Button("Handeln");
trade.addClickCommands(s-> ifTopDialog( () -> {
close();
trade.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
setTrades();
app.getGameLogic().send(new TradeOffer(tradeHandler));
close();
}));
buttons.addChild(cancel);
@ -98,6 +105,26 @@ public class TradeMenu extends Dialog {
return mainContent;
}
private void setTrades() {
tradeHandler.setOfferedAmount(Integer.parseInt(leftCurrencyInput.getText()));
tradeHandler.setRequestedAmount(Integer.parseInt(rightCurrencyInput.getText()));
tradeHandler.setOfferedJailCards(Integer.parseInt(leftSpecialCardSelector.getSelectedItem()));
tradeHandler.setRequestedJailCards(Integer.parseInt(rightSpecialCardSelector.getSelectedItem()));
Set<PropertyField> offeredProperties = new HashSet<>();
for (String propertyString : leftselBuildings) {
offeredProperties.add( (PropertyField) app.getGameLogic().getBoardManager().getFieldByName(propertyString));
}
Set<PropertyField> requestedProperties = new HashSet<>();
for (String propertyString : rightselBuildings) {
requestedProperties.add( (PropertyField) app.getGameLogic().getBoardManager().getFieldByName(propertyString));
}
tradeHandler.setOfferedProperties(offeredProperties);
tradeHandler.setRequestedProperties(requestedProperties);
}
private Container createTradeColumn(String label, boolean isLeft) {
Container column = new Container(new SpringGridLayout(Axis.Y, Axis.X));
column.setBackground(new QuadBackgroundComponent(ColorRGBA.White));
@ -108,7 +135,6 @@ public class TradeMenu extends Dialog {
column.addChild(new Label("Gebäude:"));
Selector<String> buildingSelector = createPropertySelector(isLeft);
buildingSelector.getPopupContainer().setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
column.addChild(buildingSelector);
column.addChild(new Label("Währung:"));
@ -116,8 +142,7 @@ public class TradeMenu extends Dialog {
column.addChild(currencyInput);
column.addChild(new Label("Sonderkarten:"));
Selector<String> specialCardSelector = createSpecialCardSelector();
specialCardSelector.getPopupContainer().setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
Selector<String> specialCardSelector = createSpecialCardSelector(isLeft);
styleSelector(specialCardSelector);
column.addChild(specialCardSelector);
@ -135,10 +160,10 @@ public class TradeMenu extends Dialog {
return selector;
}
private Selector<String> createSpecialCardSelector() {
private Selector<String> createSpecialCardSelector(boolean isLeft) {
VersionedList<String> numbers = new VersionedList<>();
for (int i = 0; i <= app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId()).getNumJailCard(); i++) {
numbers.add(i+"");
for (int i = 0; i <= app.getGameLogic().getPlayerHandler().getPlayerById(isLeft ? tradeHandler.getReceiver().getId() : tradeHandler.getSender().getId()).getNumJailCard(); i++) {
numbers.add(i + "");
}
Selector<String> selector = new Selector<>(numbers, "glass");
styleSelector(selector);
@ -147,72 +172,43 @@ public class TradeMenu extends Dialog {
private Iterable<PropertyField> getPropertyFields(boolean isLeft) {
return app.getGameLogic()
.getBoardManager()
.getPropertyFields(app.getGameLogic()
.getPlayerHandler()
.getPlayerById(isLeft ? tradeHandler.getReceiver().getId() : tradeHandler.getSender().getId())
.getProperties());
.getBoardManager()
.getPropertyFields(app.getGameLogic()
.getPlayerHandler()
.getPlayerById(isLeft ? tradeHandler.getReceiver().getId() : tradeHandler.getSender().getId())
.getProperties());
}
private TextField createCurrencyInput() {
TextField currencyInput = new TextField("");
TextField currencyInput = new TextField("0");
styleTextField(currencyInput);
return currencyInput;
}
/**
* Creates the middle section with selection fields and arrows.
*
* @return The middle section container.
*/
private Container createMiddleSection() {
Container middleSection = new Container(new SpringGridLayout(Axis.Y, Axis.X));
middleSection.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f)));
// Add combined label for the top
Label middleLabelTop = middleSection.addChild(new Label("Gebäude: Währung: Sonderkarten:"));
middleLabelTop.setFontSize(24);
middleLabelTop.setInsets(new Insets3f(5, 5, 5, 5));
// Add the left selection field (Quellobjekte)
leftSelectionsField = middleSection.addChild(new TextField(""));
leftSelectionsField.setPreferredSize(new Vector3f(600, 50, 0));
// Add arrows
Label arrows = middleSection.addChild(new Label(""));
arrows.setFontSize(40);
// Add the right selection field (Zielobjekte)
rightSelectionsField = middleSection.addChild(new TextField(""));
rightSelectionsField.setPreferredSize(new Vector3f(600, 50, 0));
// Add combined label for the bottom
Label middleLabelBottom = middleSection.addChild(new Label("Gebäude: Währung: Sonderkarten:"));
middleLabelBottom.setFontSize(24);
middleLabelBottom.setInsets(new Insets3f(5, 5, 5, 5));
// Spacer
Label spacer = middleSection.addChild(new Label(""));
spacer.setPreferredSize(new Vector3f(1, 50, 0));
return middleSection;
}
private TextField createSelectionsField(Container parent, boolean isLeft) {
TextField field = new TextField("");
field.setPreferredSize(new Vector3f(600, 50, 0));
parent.addChild(field);
return field;
}
private Label createArrowLabel() {
Label arrowLabel = new Label("");
arrowLabel.setFontSize(40);
return arrowLabel;
}
private void styleSelector(Selector<String> selector) {
selector.setInsets(new Insets3f(5, 10, 5, 10));
selector.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
@ -246,7 +242,7 @@ public class TradeMenu extends Dialog {
private void addBackgroundImage() {
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry background = new Geometry("Background", quad);
background = new Geometry("Background", quad);
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
backgroundMaterial.setTexture("ColorMap", backgroundImage);
background.setMaterial(backgroundMaterial);
@ -254,6 +250,56 @@ public class TradeMenu extends Dialog {
app.getGuiNode().attachChild(background);
}
private void initializeReferences() {
leftBuildingRef = leftBuildingSelector.getSelectionModel().createReference();
leftCardRef = leftSpecialCardSelector.getSelectionModel().createReference();
leftCurrencyRef = leftCurrencyInput.getDocumentModel().createReference();
rightBuildingRef = rightBuildingSelector.getSelectionModel().createReference();
rightCardRef = rightSpecialCardSelector.getSelectionModel().createReference();
rightCurrencyRef = rightCurrencyInput.getDocumentModel().createReference();
}
@Override
public void update(float delta) {
if (leftBuildingRef.update() || leftCardRef.update() || leftCurrencyRef.update()) {
updateSelections(leftSelectionsField, leftBuildingSelector, leftCurrencyInput, leftSpecialCardSelector, true);
}
if (rightBuildingRef.update() || rightCardRef.update() || rightCurrencyRef.update()) {
updateSelections(rightSelectionsField, rightBuildingSelector, rightCurrencyInput, rightSpecialCardSelector, false);
}
}
private void updateSelections(TextField target, Selector<String> building, TextField currency, Selector<String> card, boolean isLeft) {
StringBuilder buildingText = new StringBuilder();
if (isLeft) {
if (leftselBuildings.contains(building.getSelectedItem())) {
leftselBuildings.remove(building.getSelectedItem()); // Remove if already selected
} else {
leftselBuildings.add(building.getSelectedItem()); // Add if not already selected
}
for (String property : leftselBuildings) {
buildingText.append(property);
buildingText.append(", ");
}
} else {
if (rightselBuildings.contains(building.getSelectedItem())) {
rightselBuildings.remove(building.getSelectedItem()); // Remove if already selected
} else {
rightselBuildings.add(building.getSelectedItem()); // Add if not already selected
}
for (String property : rightselBuildings) {
buildingText.append(property);
buildingText.append(", ");
}
}
String currencyText = currency.getText() != null ? currency.getText().trim() : "";
String cardText = card.getSelectedItem() != null ? card.getSelectedItem() : "";
target.setText(String.join(" | ", buildingText, currencyText, cardText));
}
@Override
public void escape() {
new SettingsMenu(app).open();
@ -262,44 +308,7 @@ public class TradeMenu extends Dialog {
@Override
public void close() {
app.getGuiNode().detachChild(mainContainer);
app.getGuiNode().detachChild(background);
super.close();
}
/**
* Updates the dialog periodically, called by the dialog manager.
*
* @param delta The time elapsed since the last update.
*/
@Override
public void update(float delta) {
// Check if the selection has changed
// if (selectionRef.update()) {
// String selected = playerSelector.getSelectedItem();
// if (!selected.equals(lastSelected)) {
// lastSelected = selected;
// onDropdownSelectionChanged(selected);
}
}
/**
* Handles dropdown selection changes and updates the trade handler.
*
* @param selected The selected item from the dropdown.
*/
/* private void onDropdownSelectionChanged(String selected) {
app.getGameLogic().playSound(Sound.BUTTON);
int idStart = selected.indexOf("(ID: ") + 5; // Find start of the ID
int idEnd = selected.indexOf(")", idStart); // Find end of the ID
String idStr = selected.substring(idStart, idEnd); // Extract the ID as a string
int playerId = Integer.parseInt(idStr); // Convert the ID to an integer
// Find the player by ID
Player selectedPlayer = app.getGameLogic().getPlayerHandler().getPlayerById(playerId);
if (selectedPlayer != null) {
}
}*/
}

View File

@ -300,13 +300,13 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
*/
@Override
public void received(TradeReply msg) {
if (msg.getTradeHandler().getStatus()) {
// if (msg.getTradeHandler().getStatus()) {
playSound(Sound.TRADE_ACCEPTED);
} else {
// playSound(Sound.TRADE_ACCEPTED);
// } else {
playSound(Sound.TRADE_REJECTED);
}
// playSound(Sound.TRADE_REJECTED);
// }
}
/**
@ -316,7 +316,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
*/
@Override
public void received(TradeRequest msg) {
System.out.println("Angebot angekommen");
notifyListeners(new PopUpEvent("tradeRequest"));
}
/**

View File

@ -232,11 +232,11 @@ public class ServerGameLogic implements ClientInterpreter {
@Override
public void received(TradeOffer msg, int from) {
Player sender = playerHandler.getPlayerById(from);
Player receiver = playerHandler.getPlayerById(msg.getReceiverId());
Player receiver = msg.getTradeHandler().getReceiver();
if (sender != null && receiver != null) {
LOGGER.log(Level.INFO, "Player {0} offers a trade to player {1}", sender.getName(), receiver.getName());
send(playerHandler.getPlayerById(msg.getReceiverId()), new TradeRequest(msg.getReceiverId(), msg.getTradeHandler()));
send(receiver, new TradeRequest(msg.getTradeHandler()));
}
}

View File

@ -9,7 +9,6 @@ import pp.monopoly.model.TradeHandler;
*/
@Serializable
public class TradeOffer extends ClientMessage{
private int receiverId;
private TradeHandler tradehandler;
/**
@ -23,12 +22,10 @@ public class TradeOffer extends ClientMessage{
* @param receiverId the ID of the player receiving the Request
* @param tradehandler the tradehandler
*/
public TradeOffer(int receiverId, TradeHandler tradehandler) {
this.receiverId = receiverId;
public TradeOffer(TradeHandler tradehandler) {
this.tradehandler = tradehandler;
}
public int getReceiverId() { return receiverId; }
public TradeHandler getTradeHandler() { return tradehandler; }
@Override

View File

@ -9,7 +9,6 @@ import pp.monopoly.model.TradeHandler;
*/
@Serializable
public class TradeRequest extends ServerMessage{
private int receiverId;
private TradeHandler tradehandler;
@ -24,12 +23,10 @@ public class TradeRequest extends ServerMessage{
* @param receiverId the ID of the player receiving the Request
* @param tradehandler the tradehandler
*/
public TradeRequest(int receiverId, TradeHandler tradehandler) {
this.receiverId = receiverId;
public TradeRequest(TradeHandler tradehandler) {
this.tradehandler = tradehandler;
}
public int getReceiverId() { return receiverId; }
public TradeHandler getTradeHandler() { return tradehandler; }

View File

@ -3,23 +3,30 @@ package pp.monopoly.model;
import pp.monopoly.game.server.Player;
import pp.monopoly.model.fields.PropertyField;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import com.jme3.network.serializing.Serializable;
/**
* Handles a single trade between two players.
* Encapsulates trade details, validation, acceptance, and rejection.
*/
@Serializable
public class TradeHandler {
private final Player sender;
private Player receiver;
private int offeredAmount;
private List<PropertyField> offeredProperties;
private Set<PropertyField> offeredProperties = new HashSet<>();
private int offeredJailCards;
private int requestedAmount;
private List<PropertyField> requestedProperties;
private Set<PropertyField> requestedProperties = new HashSet<>();
private int requestedJailCards;
private Boolean status = null;
private TradeHandler() {
sender = null;
}
/**
* Constructs a TradeHandler for a single trade instance.
@ -33,8 +40,8 @@ public class TradeHandler {
* @param requestedProperties the properties requested from the receiver
* @param requestedJailCards the jail cards requested from the receiver
*/
public TradeHandler(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties,
int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) {
public TradeHandler(Player sender, Player receiver, int offeredAmount, Set<PropertyField> offeredProperties,
int offeredJailCards, int requestedAmount, Set<PropertyField> requestedProperties, int requestedJailCards) {
this.sender = sender;
this.receiver = receiver;
this.offeredAmount = offeredAmount;
@ -69,7 +76,7 @@ public class TradeHandler {
return offeredJailCards;
}
public List<PropertyField> getOfferedProperties() {
public Set<PropertyField> getOfferedProperties() {
return offeredProperties;
}
@ -85,7 +92,7 @@ public class TradeHandler {
return requestedJailCards;
}
public List<PropertyField> getRequestedProperties() {
public Set<PropertyField> getRequestedProperties() {
return requestedProperties;
}
@ -93,10 +100,6 @@ public class TradeHandler {
return sender;
}
public Boolean getStatus() {
return status;
}
/**
* Initiates the trade and validates its terms.
*
@ -234,7 +237,7 @@ public class TradeHandler {
this.offeredJailCards = offeredJailCards;
}
public void setOfferedProperties(List<PropertyField> offeredProperties) {
public void setOfferedProperties(Set<PropertyField> offeredProperties) {
this.offeredProperties = offeredProperties;
}
@ -250,7 +253,7 @@ public class TradeHandler {
this.requestedJailCards = requestedJailCards;
}
public void setRequestedProperties(List<PropertyField> requestedProperties) {
public void setRequestedProperties(Set<PropertyField> requestedProperties) {
this.requestedProperties = requestedProperties;
}
}

View File

@ -72,6 +72,15 @@ public class BoardManager {
return fields;
}
public Field getFieldByName(String name) {
for (Field field : board) {
if (field.getName().equals(name)) {
return field;
}
}
throw new NoSuchElementException();
}
/**
* Method to find the Field at specific index

View File

@ -44,10 +44,13 @@ import pp.monopoly.message.server.GameStart;
import pp.monopoly.message.server.NextPlayerTurn;
import pp.monopoly.message.server.PlayerStatusUpdate;
import pp.monopoly.message.server.ServerMessage;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.Figure;
import pp.monopoly.model.IntPoint;
import pp.monopoly.model.LimitedLinkedList;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.fields.BoardManager;
import pp.monopoly.model.fields.BuildingProperty;
import pp.monopoly.model.fields.EventField;
@ -164,6 +167,9 @@ public class MonopolyServer implements MessageListener<HostedConnection>, Connec
Serializer.registerClass(EventField.class);
Serializer.registerClass(GulagField.class);
Serializer.registerClass(FineField.class);
Serializer.registerClass(TradeRequest.class);
Serializer.registerClass(TradeReply.class);
Serializer.registerClass(TradeHandler.class);
}
private void registerListeners() {