Question might work?

This commit is contained in:
gamer147
2025-11-24 15:29:01 -05:00
parent 7cc3f0e184
commit 7d35101dbf
2 changed files with 180 additions and 1 deletions

View File

@@ -2,28 +2,115 @@ package com.wurmonline.server.questions;
import com.wurmonline.server.NoSuchPlayerException;
import com.wurmonline.server.Players;
import com.wurmonline.server.players.Player;
import mod.treestar.shopmod.ShopService;
import mod.treestar.shopmod.datamodels.ShopCategory;
import mod.treestar.shopmod.datamodels.ShopItem;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
public class ShopQuestion extends Question {
private static final int SHOP_QUESTION_ID = 90001;
private ShopService shopService;
private int selectedCategoryId = -1;
public ShopQuestion(long responderId, String shopName, ShopService shopService) throws NoSuchPlayerException {
super(Players.getInstance().getPlayer(responderId), shopName, null, SHOP_QUESTION_ID, responderId);
this.shopService = shopService;
List<ShopCategory> categories = shopService.getCategories();
if (!categories.isEmpty()) {
selectedCategoryId = categories.get(0).getId();
}
}
@Override
public void answer(Properties properties) {
super.answer(properties);
List<ShopCategory> categories = shopService.getCategories();
// Update category selection if present
String categoryIndex = properties.getProperty("category");
if (categoryIndex != null && !categories.isEmpty()) {
try {
int idx = Integer.parseInt(categoryIndex);
if (idx >= 0 && idx < categories.size()) {
selectedCategoryId = categories.get(idx).getId();
}
} catch (NumberFormatException ignored) { }
}
// If purchase not requested, refresh UI with selected category
if (!properties.containsKey("submit")) {
sendQuestion();
return;
}
String itemIdStr = properties.getProperty("itemid");
if (itemIdStr == null) {
getResponder().getCommunicator().sendNormalServerMessage("No item selected.");
return;
}
int itemId;
try {
itemId = Integer.parseInt(itemIdStr);
} catch (NumberFormatException e) {
getResponder().getCommunicator().sendNormalServerMessage("Invalid item selected.");
return;
}
ShopService.PurchaseResult result = shopService.purchaseItem((Player)getResponder(), itemId);
if (result.isSuccess()) {
getResponder().getCommunicator().sendSafeServerMessage(result.getMessage());
} else {
getResponder().getCommunicator().sendNormalServerMessage(result.getMessage());
}
}
@Override
public void sendQuestion() {
super.sendQuestion();
List<ShopCategory> categories = shopService.getCategories();
if (categories.isEmpty()) {
getResponder().getCommunicator().sendNormalServerMessage("No shop categories are available.");
return;
}
if (selectedCategoryId == -1 || categories.stream().noneMatch(c -> c.getId() == selectedCategoryId)) {
selectedCategoryId = categories.get(0).getId();
}
int defaultCategoryIndex = 0;
for (int i = 0; i < categories.size(); i++) {
if (categories.get(i).getId() == selectedCategoryId) {
defaultCategoryIndex = i;
break;
}
}
List<ShopItem> items = shopService.getItems().stream()
.filter(i -> i.getCategoryId() == selectedCategoryId)
.collect(Collectors.toList());
if (items.isEmpty()) {
getResponder().getCommunicator().sendNormalServerMessage("No shop items are available.");
return;
}
StringBuilder bml = new StringBuilder();
bml.append("border{center{heading{text=\"").append(escape(title)).append("\"}}");
if (categories.size() > 1) {
bml.append("harray{label{text=\"Category\"};dropdown{id=\"category\";options=\"")
.append(categories.stream().map(c -> escape(c.getName())).collect(Collectors.joining(",")))
.append("\";default=\"").append(defaultCategoryIndex).append("\"}}");
}
bml.append("center{scroll{table{rows=\"");
for (ShopItem item : items) {
bml.append("label{text=\"").append(escape(item.getName())).append("\"};");
bml.append("label{text=\"").append(escape(item.getDescription())).append("\"};");
bml.append("label{text=\"").append(escape(item.getPriceDisplay())).append("\"};");
bml.append("radio{group=\"itemid\";id=\"").append(item.getId()).append("\"};");
}
bml.append("\"}}}");
bml.append("harray{button{id=\"submit\";text=\"Purchase\"};button{id=\"cancel\";text=\"Cancel\"}}");
bml.append("}");
getResponder().getCommunicator().sendBml(400, 400, true, true, bml.toString(), 200, 200, 200, title);
}
public ShopService getShopService() {
@@ -33,4 +120,8 @@ public class ShopQuestion extends Question {
public void setShopService(ShopService shopService) {
this.shopService = shopService;
}
private String escape(String value) {
return value == null ? "" : value.replace("\"", "''");
}
}

View File

@@ -1,12 +1,21 @@
package mod.treestar.shopmod;
import com.wurmonline.server.players.Player;
import mod.treestar.shopmod.categoryprovider.ShopCategoryProvider;
import mod.treestar.shopmod.itemprovider.ShopItemProvider;
import mod.treestar.shopmod.datamodels.ShopCategory;
import mod.treestar.shopmod.datamodels.ShopItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ShopService {
private static final Logger logger = Logger.getLogger(ShopService.class.getName());
private List<ShopCategoryProvider> categoryProviders = new ArrayList<>();
private List<ShopItemProvider> itemProviders = new ArrayList<>();
@@ -20,6 +29,59 @@ public class ShopService {
itemProviders.add(provider);
}
public List<ShopCategory> getCategories() {
List<ShopCategory> categories = new ArrayList<>();
for (ShopCategoryProvider provider : categoryProviders) {
List<ShopCategory> provided = provider.getCategories();
if (provided != null) {
categories.addAll(provided);
}
}
return categories;
}
public List<ShopItem> getItems() {
List<ShopItem> items = new ArrayList<>();
for (ShopItemProvider provider : itemProviders) {
List<ShopItem> provided = provider.getItems();
if (provided != null) {
items.addAll(provided);
}
}
return items;
}
public ShopItem getItemById(int id) {
return getItems().stream().filter(i -> i.getId() == id).findFirst().orElse(null);
}
public PurchaseResult purchaseItem(Player player, int itemId) {
ShopItem item = getItemById(itemId);
if (item == null) {
return PurchaseResult.failure("Item not found.");
}
if (item.getCurrency() == null) {
return PurchaseResult.failure("Item has no currency configured.");
}
if (item.getPurchaseHandler() == null) {
return PurchaseResult.failure("Item has no purchase handler configured.");
}
if (!item.getCurrency().canPlayerAfford(player)) {
return PurchaseResult.failure("You cannot afford this item.");
}
boolean charged = item.getCurrency().chargePlayer(player);
if (!charged) {
return PurchaseResult.failure("Charging failed; purchase canceled.");
}
try {
item.getPurchaseHandler().onPurchase(player);
return PurchaseResult.success("Purchase successful.");
} catch (Exception e) {
logger.log(Level.WARNING, "Purchase handler failed for item " + itemId + " for player " + player.getName(), e);
return PurchaseResult.failure("An error occurred while delivering the item.");
}
}
public static ShopService getInstance() {
if(instance == null) {
@@ -34,4 +96,30 @@ public class ShopService {
public static ShopService create() {
return new ShopService();
}
public static class PurchaseResult {
private final boolean success;
private final String message;
private PurchaseResult(boolean success, String message) {
this.success = success;
this.message = message;
}
public static PurchaseResult success(String message) {
return new PurchaseResult(true, message);
}
public static PurchaseResult failure(String message) {
return new PurchaseResult(false, message);
}
public boolean isSuccess() {
return success;
}
public String getMessage() {
return message;
}
}
}