Drafts have chat rooms; Mixed drafts renames to Fusion drafts; Information about number of packs drafted is displayed; Draft state check is now interval instead of repeated time out; Draft comm errors are now appended to chat; Solo table draft tournaments removed from game hall; Fixed tournament broadcast to all players if all players dropped; Newly picked cards are put at the end of all picked cards

This commit is contained in:
jakub.salavec
2025-03-19 17:16:14 +01:00
parent 08b9da67fc
commit fe8da38619
20 changed files with 259 additions and 88 deletions

View File

@@ -253,6 +253,8 @@ public class TableDraftRequestHandler extends LotroServerRequestHandler implemen
// No timer
}
appendRoundsInfo(doc, rootElement);
return doc;
}
@@ -278,6 +280,13 @@ public class TableDraftRequestHandler extends LotroServerRequestHandler implemen
rootElement.appendChild(time);
}
private void appendRoundsInfo(Document doc, Element rootElement) {
Element time = doc.createElement("roundsInfo");
time.setAttribute("currentRound", "" + draftPlayer.getTableStatus().getCurrentRound());
time.setAttribute("roundsTotal", "" + draftPlayer.getTableStatus().getRoundsTotal());
rootElement.appendChild(time);
}
private void appendPickedCards(Document doc, Element rootElement) {
SortAndFilterCards sortAndFilterCards = new SortAndFilterCards();
List<CardCollection.Item> pickedCards = sortAndFilterCards.process(

View File

@@ -13,10 +13,15 @@ var GempLotrTableDraftUI = Class.extend({
eventId:null,
refreshInterval:null,
chatBoxDiv: null,
chatBox: null,
init:function () {
var that = this;
this.comm = new GempLotrCommunication("/gemp-lotr-server", that.processError);
this.comm = new GempLotrCommunication("/gemp-lotr-server", that.processError.bind(that));
this.eventId = getUrlParam("eventId");
@@ -27,6 +32,7 @@ var GempLotrTableDraftUI = Class.extend({
this.tableStatusDiv = $("#tableStatusDiv");
this.picksDiv = $("#picksDiv");
this.draftedDiv = $("#draftedDiv");
this.sideDiv = $("#sideDiv");
this.picksCardGroup = new NormalCardGroup(this.picksDiv, function (card) {
return true;
@@ -40,6 +46,8 @@ var GempLotrTableDraftUI = Class.extend({
this.selectionFunc = this.addCardToDeckAndLayout;
this.addBottomLeftTabPane();
$("body").click(
function (event) {
return that.clickCardFunction(event);
@@ -86,7 +94,50 @@ var GempLotrTableDraftUI = Class.extend({
};
this.infoDialog.swipe(swipeOptions);
this.refreshInterval = setInterval(function () {
that.getDraftState();
}, 500);
this.getDraftState();
this.chatBox.beginGameChat();
},
addBottomLeftTabPane: function () {
var that = this;
var tabsLabels = "<li><a href='#chatBox' class='slimTab'>Chat</a></li><li><a href='#playersInRoomBox' class='slimTab'>Players</a></li>";
var tabsBodies = "<div id='chatBox' class='slimPanel'></div><div id='playersInRoomBox' class='slimPanel'></div>";
var tabsStr = "<div id='bottomLeftTabs'><ul>" + tabsLabels + "</ul>" + tabsBodies + "</div>";
this.tabPane = $(tabsStr).tabs();
$("#sideDiv").append(this.tabPane);
this.chatBoxDiv = $("#chatBox");
var playerListener = function (players) {
var val = "";
for (var i = 0; i < players.length; i++)
val += players[i] + "<br/>";
$("a[href='#playersInRoomBox']").html("Players(" + players.length + ")");
$("#playersInRoomBox").html(val);
};
var displayChatListener = function(title, message) {
var dialog = $("<div></div>").dialog({
title: title,
resizable: true,
height: 200,
modal: true,
buttons: {}
}).html(message);
}
var chatRoomName = ("Draft-" + getUrlParam("eventId"));
this.chatBox = new ChatBoxUI(chatRoomName, $("#chatBox"), this.comm.url, false, playerListener, false, displayChatListener);
this.chatBox.chatUpdateInterval = 3000;
},
processDraftStatus:function (xml, callUpdate) {
@@ -96,6 +147,7 @@ var GempLotrTableDraftUI = Class.extend({
var pickedCards = root.getElementsByTagName("pickedCard");
var availablePicks = root.getElementsByTagName("availablePick");
var timeRemainingElements = root.getElementsByTagName("timeRemaining");
var roundsInfoElements = root.getElementsByTagName("roundsInfo");
var playerElements = root.getElementsByTagName("player");
var pickOrderAscendingElements = root.getElementsByTagName("pickOrderAscending");
@@ -105,6 +157,14 @@ var GempLotrTableDraftUI = Class.extend({
timeRemaining = timeRemainingElements[0].getAttribute("value");
}
// Get round info
var currentRound = null; // Default to null
var roundsTotal = null; // Default to null
if (roundsInfoElements.length > 0) {
currentRound = roundsInfoElements[0].getAttribute("currentRound");
roundsTotal = roundsInfoElements[0].getAttribute("roundsTotal");
}
// Check if picked cards changed and we should update
let pickedCardsChanged = false;
@@ -113,7 +173,7 @@ var GempLotrTableDraftUI = Class.extend({
// Count occurrences of picked cards
for (var i = 0; i < pickedCards.length; i++) {
let blueprintId = pickedCards[i].getAttribute("blueprintId");
newDraftedIds.set(blueprintId, (newDraftedIds.get(blueprintId) || 0) + 1);
newDraftedIds.set(blueprintId, pickedCards[i].getAttribute("count"));
}
// Count occurrences of existing drafted cards
@@ -128,13 +188,54 @@ var GempLotrTableDraftUI = Class.extend({
pickedCardsChanged = true;
} else {
for (let [id, count] of newDraftedIds) {
if (existingDraftedIds.get(id) !== count) {
if (existingDraftedIds.get(id) != count) {
pickedCardsChanged = true;
break;
}
}
}
// Check if we can append just one card
let singleNewCard = null;
let totalDifference = 0;
for (let [id, newCount] of newDraftedIds) {
let existingCount = existingDraftedIds.get(id) || 0;
let difference = newCount - existingCount;
if (difference > 0) {
singleNewCard = singleNewCard === null ? id : null; // Ensure only one new card
totalDifference += difference;
}
}
// There is exactly one new card if totalDifference is 1 and singleNewCard is set
let isSingleNewCard = totalDifference === 1 && singleNewCard !== null;
if (isSingleNewCard) {
var card = new Card(singleNewCard, null, null, "drafted", "deck", "player");
var cardDiv = Card.CreateCardDiv(card.imageUrl, null, null, card.isFoil(), false, false, card.hasErrata(), false);
cardDiv.data("card", card);
cardDiv.data("blueprintId", singleNewCard);
that.draftedDiv.append(cardDiv);
that.draftedCardGroup.layoutCards();
} else if (pickedCardsChanged) {
$(".card", that.draftedDiv).remove();
for (var i = 0; i < pickedCards.length; i++) {
var pickedCard = pickedCards[i];
var blueprintId = pickedCard.getAttribute("blueprintId");
var count = pickedCard.getAttribute("count");
for (var no = 0; no < count; no++) {
var card = new Card(blueprintId, null, null, "drafted", "deck", "player");
var cardDiv = Card.CreateCardDiv(card.imageUrl, null, null, card.isFoil(), false, false, card.hasErrata(), false);
cardDiv.data("card", card);
cardDiv.data("blueprintId", blueprintId);
that.draftedDiv.append(cardDiv);
}
}
that.draftedCardGroup.layoutCards();
}
// Check if cards to pick from changed and we should update
let availablePicksChanged = false;
let newPickIds = new Map();
@@ -183,23 +284,6 @@ var GempLotrTableDraftUI = Class.extend({
chosenCardChanged = true;
}
if (pickedCardsChanged) {
$(".card", that.draftedDiv).remove();
for (var i = 0; i < pickedCards.length; i++) {
var pickedCard = pickedCards[i];
var blueprintId = pickedCard.getAttribute("blueprintId");
var count = pickedCard.getAttribute("count");
for (var no = 0; no < count; no++) {
var card = new Card(blueprintId, null, null, "drafted", "deck", "player");
var cardDiv = Card.CreateCardDiv(card.imageUrl, null, null, card.isFoil(), false, false, card.hasErrata(), false);
cardDiv.data("card", card);
cardDiv.data("blueprintId", blueprintId);
that.draftedDiv.append(cardDiv);
}
}
that.draftedCardGroup.layoutCards();
}
if (availablePicksChanged) {
$(".card", that.picksDiv).remove();
for (var i = 0; i < availablePicks.length; i++) {
@@ -279,26 +363,25 @@ var GempLotrTableDraftUI = Class.extend({
if (newChosenIds.size != 0) {
let message = "Waiting for others to pick a card";
if (currentRound !== null && roundsTotal !== null) {
message += " - Pack " + currentRound + "/" + roundsTotal;
}
if (timeRemaining !== null) {
message += " (" + formatTime(timeRemaining) + ")";
}
that.messageDiv.text(message);
setTimeout(function () {
that.getDraftState();
}, 500);
} else if (availablePicks.length > 0) {
let message = "Make a pick";
if (currentRound !== null && roundsTotal !== null) {
message += " - Pack " + currentRound + "/" + roundsTotal;
}
if (timeRemaining !== null) {
message += " (" + formatTime(timeRemaining) + ")";
}
that.messageDiv.text(message);
setTimeout(function () {
that.getDraftState();
}, 500);
} else {
that.messageDiv.text("Draft is finished");
clearInterval(that.refreshInterval);
}
}
},
@@ -410,6 +493,8 @@ var GempLotrTableDraftUI = Class.extend({
var messageHeight = 40;
var statusHeight = 20;
var padding = 5;
var chatHeight = 200;
var chatWidth = 200;
var topWidth = this.topDiv.width();
var topHeight = this.topDiv.height();
@@ -428,8 +513,19 @@ var GempLotrTableDraftUI = Class.extend({
this.picksDiv.css({position:"absolute", left:padding, top:messageHeight+statusHeight+padding*2, width:topWidth-padding*2, height:topHeight-messageHeight-statusHeight-padding*2});
this.picksCardGroup.setBounds(0, 0, topWidth-padding*2, topHeight-messageHeight-statusHeight-padding*2);
this.draftedDiv.css({position:"absolute", left:padding, top:padding, width:bottomWidth-padding*2, height:bottomHeight-padding*2});
this.draftedCardGroup.setBounds(0, 0, bottomWidth-padding*2, bottomHeight-padding*2);
this.draftedDiv.css({position:"absolute", left:padding*2+chatWidth, top:padding, width:bottomWidth-padding*2-chatWidth, height:bottomHeight-padding*2});
this.draftedCardGroup.setBounds(0, 0, bottomWidth-padding*2-chatWidth, bottomHeight-padding*2);
this.sideDiv.css({position:"absolute", left:padding, top:padding, width:chatWidth, height:bottomHeight-padding*2});
this.tabPane.css({
position: "absolute",
left: 0,
top: bottomHeight - chatHeight - padding,
width: chatWidth - padding,
height: chatHeight - padding
});
this.chatBox.setBounds(4, 4 + 25, chatWidth - 8, chatHeight - 8 - 25);
} else {
this.picksCardGroup.layoutCards();
this.draftedCardGroup.layoutCards();
@@ -437,7 +533,10 @@ var GempLotrTableDraftUI = Class.extend({
},
processError:function (xhr, ajaxOptions, thrownError) {
if (thrownError != "abort")
alert("There was a problem during communication with server");
if (thrownError != "abort") {
clearInterval(this.refreshInterval);
this.chatBox.appendMessage("There was a problem communicating with the server, if the draft is finished, table has been removed, otherwise you have lost connection to the server.", "warningMessage");
this.chatBox.appendMessage("Refresh the page (press F5) to resume the draft, or press back on your browser to get back to the Game Hall.", "warningMessage");
}
}
});

View File

@@ -11,6 +11,8 @@
<link rel="manifest" href="images/icons/site.webmanifest">
<link rel="stylesheet" type="text/css" href="css/gemp-001/deckBuild.css">
<!-- styles for chat messages -->
<link rel="stylesheet" type="text/css" href="css/gemp-001/game.css">
<link rel="stylesheet" type="text/css" href="css/dark-hive/jquery-ui-1.8.16.custom.css">
<link rel="stylesheet" type="text/css" href="css/jquery.contextMenu.css">
@@ -70,6 +72,7 @@
<div id="picksDiv"></div>
</div>
<div id="bottomDiv" class="ui-layout-center">
<div id="sideDiv"></div>
<div id="draftedDiv"></div>
</div>
</body>

View File

@@ -96,6 +96,15 @@ public class ServerBuilder {
extract(objectMap, LoggedUserHolder.class)
));
objectMap.put(MerchantService.class,
new MerchantService(
extract(objectMap, LotroCardBlueprintLibrary.class),
extract(objectMap, CollectionsManager.class)));
objectMap.put(ChatServer.class, new ChatServer(
extract(objectMap, IgnoreDAO.class),
extract(objectMap, PlayerDAO.class)));
objectMap.put(TournamentService.class,
new TournamentService(
extract(objectMap, CollectionsManager.class),
@@ -108,16 +117,8 @@ public class ServerBuilder {
extract(objectMap, LotroCardBlueprintLibrary.class),
extract(objectMap, LotroFormatLibrary.class),
extract(objectMap, SoloDraftDefinitions.class),
extract(objectMap, TableDraftDefinitions.class)));
objectMap.put(MerchantService.class,
new MerchantService(
extract(objectMap, LotroCardBlueprintLibrary.class),
extract(objectMap, CollectionsManager.class)));
objectMap.put(ChatServer.class, new ChatServer(
extract(objectMap, IgnoreDAO.class),
extract(objectMap, PlayerDAO.class)));
extract(objectMap, TableDraftDefinitions.class),
extract(objectMap, ChatServer.class)));
objectMap.put(LotroServer.class,
new LotroServer(

View File

@@ -20,10 +20,14 @@ public class ChatServer extends AbstractServer {
}
public ChatRoomMediator createChatRoom(String name, boolean muteJoinPartMessages, int secondsTimeoutPeriod,
boolean allowIncognito, String welcomeMessage) {
boolean allowIncognito, String welcomeMessage, String startMessage) {
ChatRoomMediator chatRoom = new ChatRoomMediator(_ignoreDAO, _playerDAO, name, muteJoinPartMessages, secondsTimeoutPeriod, allowIncognito, welcomeMessage);
try {
chatRoom.sendMessage("System", "Welcome to room: " + name, true);
if (startMessage == null) {
chatRoom.sendMessage("System", "Welcome to room: " + name, true);
} else {
chatRoom.sendMessage("System", startMessage, true);
}
} catch (PrivateInformationException exp) {
// Ignore, sent as admin
} catch (ChatCommandErrorException e) {

View File

@@ -36,12 +36,16 @@ public interface TableDraft {
}
class TableStatus {
private List<PlayerStatus> playerStatuses;
private boolean pickOrderAscending;
private final List<PlayerStatus> playerStatuses;
private final boolean pickOrderAscending;
private final int currentRound;
private final int roundsTotal;
public TableStatus(List<PlayerStatus> playerStatuses, boolean pickOrderAscending) {
public TableStatus(List<PlayerStatus> playerStatuses, boolean pickOrderAscending, int currentRound, int roundsTotal) {
this.playerStatuses = playerStatuses;
this.pickOrderAscending = pickOrderAscending;
this.currentRound = currentRound;
this.roundsTotal = roundsTotal;
}
public List<PlayerStatus> getPlayerStatuses() {
@@ -51,5 +55,13 @@ public interface TableDraft {
public boolean isPickOrderAscending() {
return pickOrderAscending;
}
public int getCurrentRound() {
return currentRound;
}
public int getRoundsTotal() {
return roundsTotal;
}
}
}

View File

@@ -379,6 +379,6 @@ public class TableDraftClassic implements TableDraft{
public TableStatus getTableStatus() {
List<PlayerStatus> statuses = new ArrayList<>();
players.forEach(draftPlayer -> statuses.add(new PlayerStatus(draftPlayer.getName(), chosenCards.containsKey(draftPlayer))));
return new TableStatus(statuses, currentRound % 2 == 1); // Alternate pick order with each booster
return new TableStatus(statuses, currentRound % 2 == 1, currentRound, rounds); // Alternate pick order with each booster
}
}

View File

@@ -8,6 +8,7 @@ public interface TableDraftDefinition {
TableDraft getTableDraft(CollectionsManager collectionsManager, CollectionType collectionType, DraftTimer draftTimer);
int getMaxPlayers();
String getName();
String getCode();
String getFormat();
}

View File

@@ -2,10 +2,10 @@ package com.gempukku.lotro.draft3;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.draft3.format.fotr.FotrTableDraftDefinition;
import com.gempukku.lotro.draft3.format.fotr_mixed.FotrMixedTableDraftDefinition;
import com.gempukku.lotro.draft3.format.fotr_fusion.FotrFusionTableDraftDefinition;
import com.gempukku.lotro.draft3.format.fotr_power_max.FotrPowerMaxTableDraftDefinition;
import com.gempukku.lotro.draft3.format.ttt.TttTableDraftDefinition;
import com.gempukku.lotro.draft3.format.ttt_mixed.TttMixedTableDraftDefinition;
import com.gempukku.lotro.draft3.format.ttt_fusion.TttFusionTableDraftDefinition;
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
import com.gempukku.lotro.game.formats.LotroFormatLibrary;
@@ -21,14 +21,14 @@ public class TableDraftDefinitions {
FotrTableDraftDefinition fotrTableDraftDefinition = new FotrTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(fotrTableDraftDefinition.getCode(), fotrTableDraftDefinition);
FotrMixedTableDraftDefinition fotrMixedTableDraftDefinition = new FotrMixedTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(fotrMixedTableDraftDefinition.getCode(), fotrMixedTableDraftDefinition);
FotrFusionTableDraftDefinition fotrFusionTableDraftDefinition = new FotrFusionTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(fotrFusionTableDraftDefinition.getCode(), fotrFusionTableDraftDefinition);
TttTableDraftDefinition tttTableDraftDefinition = new TttTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(tttTableDraftDefinition.getCode(), tttTableDraftDefinition);
TttMixedTableDraftDefinition tttMixedTableDraftDefinition = new TttMixedTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(tttMixedTableDraftDefinition.getCode(), tttMixedTableDraftDefinition);
TttFusionTableDraftDefinition tttFusionTableDraftDefinition = new TttFusionTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(tttFusionTableDraftDefinition.getCode(), tttFusionTableDraftDefinition);
FotrPowerMaxTableDraftDefinition fotrPowerMaxTableDraftDefinition = new FotrPowerMaxTableDraftDefinition(collectionsManager, cardLibrary, formatLibrary);
draftTypes.put(fotrPowerMaxTableDraftDefinition.getCode(), fotrPowerMaxTableDraftDefinition);

View File

@@ -56,6 +56,11 @@ public class FotrTableDraftDefinition implements TableDraftDefinition {
return PLAYER_COUNT;
}
@Override
public String getName() {
return "FotR Booster Draft";
}
@Override
public String getCode() {
return "fotr_table_draft";

View File

@@ -1,4 +1,4 @@
package com.gempukku.lotro.draft3.format.fotr_mixed;
package com.gempukku.lotro.draft3.format.fotr_fusion;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.draft3.Booster;
@@ -11,7 +11,7 @@ import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import java.util.*;
import java.util.stream.Collectors;
public class FotrMixedTableDraftBoosterProducer implements BoosterProducer {
public class FotrFusionTableDraftBoosterProducer implements BoosterProducer {
private static final int MAX_ROUND = 6;
private static final String RARE_FILTER = "rarity:R";
@@ -23,8 +23,8 @@ public class FotrMixedTableDraftBoosterProducer implements BoosterProducer {
private final Map<String, List<String>> cardPools = new HashMap<>();
public FotrMixedTableDraftBoosterProducer(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary, Map<String, Double> cardPlayRates) {
public FotrFusionTableDraftBoosterProducer(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary, Map<String, Double> cardPlayRates) {
SortAndFilterCards sortAndFilterCards = new SortAndFilterCards();
List<String> rarities = List.of("rare", "uncommon", "common");

View File

@@ -1,4 +1,4 @@
package com.gempukku.lotro.draft3.format.fotr_mixed;
package com.gempukku.lotro.draft3.format.fotr_fusion;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.db.vo.CollectionType;
@@ -11,7 +11,7 @@ import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import java.util.Map;
public class FotrMixedTableDraftDefinition implements TableDraftDefinition {
public class FotrFusionTableDraftDefinition implements TableDraftDefinition {
private static final int DRAFT_ROUNDS = 6;
private static final int PLAYER_COUNT = 6;
@@ -20,14 +20,14 @@ public class FotrMixedTableDraftDefinition implements TableDraftDefinition {
private final Map<String, Double> cardValues;
public FotrMixedTableDraftDefinition(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary) {
public FotrFusionTableDraftDefinition(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary) {
FotrDraftCardEvaluator evaluator = new FotrDraftCardEvaluator(cardLibrary);
cardValues = evaluator.getCachedValuesMap();
Map<String, Double> cardPlayRates = evaluator.getCachedPlayRateMap();
startingCollectionProducer = new FotrTableDraftStartingCollectionProducer(collectionsManager, cardLibrary, formatLibrary);
boosterProducer = new FotrMixedTableDraftBoosterProducer(collectionsManager, cardLibrary, formatLibrary, cardPlayRates);
boosterProducer = new FotrFusionTableDraftBoosterProducer(collectionsManager, cardLibrary, formatLibrary, cardPlayRates);
}
@Override
@@ -40,9 +40,14 @@ public class FotrMixedTableDraftDefinition implements TableDraftDefinition {
return PLAYER_COUNT;
}
@Override
public String getName() {
return "FotR Block Fusion Booster Draft";
}
@Override
public String getCode() {
return "fotr_mixed_table_draft";
return "fotr_fusion_table_draft";
}
@Override

View File

@@ -39,6 +39,11 @@ public class FotrPowerMaxTableDraftDefinition implements TableDraftDefinition {
return PLAYER_COUNT;
}
@Override
public String getName() {
return "FotR Block Power Max Draft";
}
@Override
public String getCode() {
return "fotr_power_max_table_draft";

View File

@@ -73,6 +73,11 @@ public class TttTableDraftDefinition implements TableDraftDefinition {
return PLAYER_COUNT;
}
@Override
public String getName() {
return "TTT Booster Draft";
}
@Override
public String getCode() {
return "ttt_table_draft";

View File

@@ -1,4 +1,4 @@
package com.gempukku.lotro.draft3.format.ttt_mixed;
package com.gempukku.lotro.draft3.format.ttt_fusion;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.draft3.Booster;
@@ -11,7 +11,7 @@ import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import java.util.*;
import java.util.stream.Collectors;
public class TttMixedTableDraftBoosterProducer implements BoosterProducer {
public class TttFusionTableDraftBoosterProducer implements BoosterProducer {
private static final int MAX_ROUND = 6;
private static final String RARE_FILTER = "rarity:R";
@@ -23,8 +23,8 @@ public class TttMixedTableDraftBoosterProducer implements BoosterProducer {
private final Map<String, List<String>> cardPools = new HashMap<>();
public TttMixedTableDraftBoosterProducer(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary, Map<String, Double> cardPlayRates) {
public TttFusionTableDraftBoosterProducer(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary, Map<String, Double> cardPlayRates) {
SortAndFilterCards sortAndFilterCards = new SortAndFilterCards();
List<String> rarities = List.of("rare", "uncommon", "common");

View File

@@ -1,4 +1,4 @@
package com.gempukku.lotro.draft3.format.ttt_mixed;
package com.gempukku.lotro.draft3.format.ttt_fusion;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.db.vo.CollectionType;
@@ -11,7 +11,7 @@ import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import java.util.Map;
public class TttMixedTableDraftDefinition implements TableDraftDefinition {
public class TttFusionTableDraftDefinition implements TableDraftDefinition {
private static final int DRAFT_ROUNDS = 6;
private static final int PLAYER_COUNT = 6;
@@ -20,14 +20,14 @@ public class TttMixedTableDraftDefinition implements TableDraftDefinition {
private final Map<String, Double> cardValues;
public TttMixedTableDraftDefinition(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary) {
public TttFusionTableDraftDefinition(CollectionsManager collectionsManager, LotroCardBlueprintLibrary cardLibrary,
LotroFormatLibrary formatLibrary) {
TttDraftCardEvaluator evaluator = new TttDraftCardEvaluator(cardLibrary);
cardValues = evaluator.getCachedValuesMap();
Map<String, Double> cardPlayRates = evaluator.getCachedPlayRateMap();
startingCollectionProducer = new TttTableDraftStartingCollectionProducer(collectionsManager, cardLibrary, formatLibrary);
boosterProducer = new TttMixedTableDraftBoosterProducer(collectionsManager, cardLibrary, formatLibrary, cardPlayRates);
boosterProducer = new TttFusionTableDraftBoosterProducer(collectionsManager, cardLibrary, formatLibrary, cardPlayRates);
}
@Override
@@ -40,9 +40,14 @@ public class TttMixedTableDraftDefinition implements TableDraftDefinition {
return PLAYER_COUNT;
}
@Override
public String getName() {
return "TTT Block Fusion Booster Draft";
}
@Override
public String getCode() {
return "ttt_mixed_table_draft";
return "ttt_fusion_table_draft";
}
@Override

View File

@@ -101,7 +101,7 @@ public class LotroServer extends AbstractServer {
allowedUsers.add(participant.getPlayerId());
_chatServer.createPrivateChatRoom(getChatRoomName(gameId), false, allowedUsers, 30);
} else
_chatServer.createChatRoom(getChatRoomName(gameId), false, 30, false, null);
_chatServer.createChatRoom(getChatRoomName(gameId), false, 30, false, null, null);
// Allow spectators for leagues, but not tournaments
// Also: yes, yes, we're very proud that you found a way to assign this boolean in one line.

View File

@@ -75,7 +75,8 @@ public class HallServer extends AbstractServer {
tableHolder = new TableHolder(leagueService, ignoreDAO);
_hallChat = _chatServer.createChatRoom("Game Hall", true, 300, true,
"You're now in the Game Hall, use /help to get a list of available commands.<br>Don't forget to check out the new Discord chat integration! Click the 'Switch to Discord' button in the lower right ---->");
"You're now in the Game Hall, use /help to get a list of available commands.<br>Don't forget to check out the new Discord chat integration! Click the 'Switch to Discord' button in the lower right ---->",
null);
_hallChat.addChatCommandCallback("ban",
new ChatCommandCallback() {
@Override
@@ -942,7 +943,7 @@ public class HallServer extends AbstractServer {
public void broadcastMessage(String message, Collection<String> toWhom) {
try {
//check-in callback
if (toWhom == null || toWhom.isEmpty()) {
if (toWhom == null ) {
_hallChat.sendMessageNoHistory("TournamentSystem", message, true);
} else {
StringBuilder builder = new StringBuilder("TournamentSystemTo:");
@@ -997,7 +998,7 @@ public class HallServer extends AbstractServer {
public void broadcastMessage(String message, Collection<String> toWhom) {
try {
//check-in callback
if (toWhom == null || toWhom.isEmpty()) {
if (toWhom == null) {
_hallChat.sendMessageNoHistory("TournamentSystem", message, true);
} else {
StringBuilder builder = new StringBuilder("TournamentSystemTo:");

View File

@@ -1,5 +1,6 @@
package com.gempukku.lotro.tournament;
import com.gempukku.lotro.chat.ChatServer;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.common.DBDefs;
import com.gempukku.lotro.common.DateUtils;
@@ -23,11 +24,18 @@ public class TableDraftTournament extends BaseTournament implements Tournament {
private TableDraftTournamentInfo tableDraftInfo;
private TableDraft table = null;
private final ChatServer chatServer;
public TableDraftTournament(TournamentService tournamentService, CollectionsManager collectionsManager, ProductLibrary productLibrary,
LotroFormatLibrary formatLibrary, SoloDraftDefinitions soloDraftDefinitions, TableDraftDefinitions tableDraftDefinitions,
TableHolder tables, String tournamentId) {
TableHolder tables, String tournamentId, ChatServer chatServer) {
super(tournamentService, collectionsManager, productLibrary, formatLibrary, soloDraftDefinitions, tableDraftDefinitions, tables, tournamentId);
this.chatServer = chatServer;
// Create draft chat room
if (getTournamentStage() == Stage.STARTING || getTournamentStage() == Stage.DRAFT) {
chatServer.createChatRoom("Draft-" + tableDraftInfo.tableDraftParams.tournamentId, false, 30, false, null,
"Welcome to room: " + _tableDraftLibrary.getTableDraftDefinition(tableDraftInfo.tableDraftParams.tableDraftFormatCode).getName());
}
}
@Override
@@ -185,6 +193,10 @@ public class TableDraftTournament extends BaseTournament implements Tournament {
_tournamentInfo.Stage = Stage.PLAYING_GAMES;
_tournamentService.recordTournamentStage(_tournamentId, getTournamentStage());
} else if (getTournamentStage() == Stage.PLAYING_GAMES) {
// Chat room no longer needed - kept alive during deck-building if people stayed longer
chatServer.destroyChatRoom("Draft-" + tableDraftInfo.tableDraftParams.tournamentId);
if (_currentlyPlayingPlayers.isEmpty()) {
if (_tournamentInfo.PairingMechanism.isFinished(getCurrentRound(), _players, _droppedPlayers)) {
result.add(finishTournament(collectionsManager));

View File

@@ -1,5 +1,6 @@
package com.gempukku.lotro.tournament;
import com.gempukku.lotro.chat.ChatServer;
import com.gempukku.lotro.common.DateUtils;
import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.common.DBDefs;
@@ -40,6 +41,7 @@ public class TournamentService {
private TableHolder _tables;
private final SoloDraftDefinitions _soloDraftLibrary;
private final TableDraftDefinitions _tableDraftLibrary;
private final ChatServer _chatServer;
private final CollectionsManager _collectionsManager;
@@ -52,7 +54,7 @@ public class TournamentService {
public TournamentService(CollectionsManager collectionsManager, ProductLibrary productLibrary, DraftPackStorage draftPackStorage,
TournamentDAO tournamentDao, TournamentPlayerDAO tournamentPlayerDao, TournamentMatchDAO tournamentMatchDao,
GameHistoryDAO gameHistoryDao, LotroCardBlueprintLibrary bpLibrary, LotroFormatLibrary formatLibrary,
SoloDraftDefinitions soloDraftLibrary, TableDraftDefinitions tableDraftDefinitions) {
SoloDraftDefinitions soloDraftLibrary, TableDraftDefinitions tableDraftDefinitions, ChatServer chatServer) {
_collectionsManager = collectionsManager;
_productLibrary = productLibrary;
_draftPackStorage = draftPackStorage;
@@ -64,6 +66,7 @@ public class TournamentService {
_formatLibrary = formatLibrary;
_soloDraftLibrary = soloDraftLibrary;
_tableDraftLibrary = tableDraftDefinitions;
_chatServer = chatServer;
}
public PairingMechanism getPairingMechanism(Tournament.PairingType pairing) {
@@ -281,15 +284,16 @@ public class TournamentService {
private void addImmediateRecurringLimitedGames() {
addImmediateRecurringTableDraft("fotr_power_max_table_draft_queue", "FotR Power Max Table Draft", "fotrPowerMaxTableDraftQueue-", "fotr_power_max_table_draft", 8, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("fotr_mixed_table_draft_queue", "FotR Mixed Table Draft", "fotrMixedTableDraftQueue-", "fotr_mixed_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("fotr_fusion_table_draft_queue", "FotR Fusion Table Draft", "fotrFusionTableDraftQueue-", "fotr_fusion_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("fotr_table_draft_queue", "FotR Table Draft", "fotrTableDraftQueue-", "fotr_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("ttt_mixed_table_draft_queue", "TTT Mixed Table Draft", "tttMixedTableDraftQueue-", "ttt_mixed_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("ttt_fusion_table_draft_queue", "TTT Fusion Table Draft", "tttFusionTableDraftQueue-", "ttt_fusion_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringTableDraft("ttt_table_draft_queue", "TTT Table Draft", "tttTableDraftQueue-", "ttt_table_draft", 6, DraftTimerFactory.Type.CLASSIC);
addImmediateRecurringSoloTableDraft("fotr_mixed_solo_table_draft_queue", "FotR Mixed Solo Table Draft", "fotrMixedSoloTableDraftQueue-", "fotr_mixed_table_draft");
addImmediateRecurringSoloTableDraft("fotr_solo_table_draft_queue", "FotR Solo Table Draft", "fotrSoloTableDraftQueue-", "fotr_table_draft");
addImmediateRecurringSoloTableDraft("ttt_mixed_solo_table_draft_queue", "TTT Mixed Solo Table Draft", "tttMixedSoloTableDraftQueue-", "ttt_mixed_table_draft");
addImmediateRecurringSoloTableDraft("ttt_solo_table_draft_queue", "TTT Solo Table Draft", "tttSoloTableDraftQueue-", "ttt_table_draft");
// Solo table drafts are better for leagues, not for tournaments
// addImmediateRecurringSoloTableDraft("fotr_fusion_solo_table_draft_queue", "FotR Fusion Solo Table Draft", "fotrFusionSoloTableDraftQueue-", "fotr_fusion_table_draft");
// addImmediateRecurringSoloTableDraft("fotr_solo_table_draft_queue", "FotR Solo Table Draft", "fotrSoloTableDraftQueue-", "fotr_table_draft");
// addImmediateRecurringSoloTableDraft("ttt_fusion_solo_table_draft_queue", "TTT Fusion Solo Table Draft", "tttFusionSoloTableDraftQueue-", "ttt_fusion_table_draft");
// addImmediateRecurringSoloTableDraft("ttt_solo_table_draft_queue", "TTT Solo Table Draft", "tttSoloTableDraftQueue-", "ttt_table_draft");
addImmediateRecurringDraft("fotr_draft_queue", "FotR Draft", "fotrDraftQueue-", "fotr_draft");
addImmediateRecurringDraft("ttt_draft_queue", "TTT Draft", "tttDraftQueue-", "ttt_draft");
@@ -588,7 +592,7 @@ public class TournamentService {
} else if (info.Parameters().type == Tournament.TournamentType.TABLE_SOLODRAFT) {
tournament = new SoloTableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid);
} else if (info.Parameters().type == Tournament.TournamentType.TABLE_DRAFT) {
tournament = new TableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid);
tournament = new TableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid, _chatServer);
}
_activeTournaments.put(tid, tournament);
@@ -620,7 +624,7 @@ public class TournamentService {
} else if (type == Tournament.TournamentType.TABLE_SOLODRAFT) {
tournament = new SoloTableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid);
} else if (type == Tournament.TournamentType.TABLE_DRAFT) {
tournament = new TableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid);
tournament = new TableDraftTournament(this, _collectionsManager, _productLibrary, _formatLibrary, _soloDraftLibrary, _tableDraftLibrary, _tables, tid, _chatServer);
}
_activeTournaments.put(tid, tournament);