mirror of
https://github.com/magefree/mage.git
synced 2025-12-21 19:11:59 -08:00
GUI - new card hints window features:
* new help window can be opened from a player panel; * it collect and show all visible game hints from all players and all zones; * it updates in real time on game update; * allows to customize visible data; * allows to open multiple windows (current limit is 5 windows, can be slow to render); * allows to minimize opened windows; * workable card popup on mouse move over card name or card id; * filter modes: * all - show hints from all players; * player - show hints from single player; * group mode: * by hints - show same hints as one with all used cards; * by cards - show full cards list with own hints; * search mode: * allows to filter card hints by player name, card name, card id or card hint; * allows to search multiple words (equals to "or") * current limitation: * card popup shows a card instead a real object, e.g. miss card hints in it (relelated to game logs problem); * unsupport of emblems, dungeons and other non card objects from a command zone; * unsupport of revealed and library's top cards; GUI - player's panel improves: * added hints helper button; * added player hithlight as possible target in choose dialogs; * improved player name button in small mode; * fixed wrong height in small mode; Other fixes: * game logs: added card popup support for logs with custom object name;
This commit is contained in:
parent
ca80849249
commit
2bbe2b3c43
16 changed files with 1229 additions and 75 deletions
129
Mage.Tests/src/test/java/org/mage/test/utils/CardHintsTest.java
Normal file
129
Mage.Tests/src/test/java/org/mage/test/utils/CardHintsTest.java
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
package org.mage.test.utils;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.CommanderCardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.util.GameLog;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CardHintsTest extends CardTestCommanderDuelBase {
|
||||
|
||||
// html logs/names used all around xmage (game logs, chats, choose dialogs, etc)
|
||||
// usage steps:
|
||||
// * server side: find game object for logs;
|
||||
// * server side: prepare html compatible log (name [id] + color + additional info)
|
||||
// * client side: inject additional elements for popup support (e.g. "a" with "href")
|
||||
// * client side: process mouse move over a href and show object data like a card popup
|
||||
|
||||
private void assertObjectHtmlLog(String originalLog, String needVisibleColorPart, String needVisibleNormalPart, String needId) {
|
||||
String needVisibleFull = needVisibleColorPart;
|
||||
if (!needVisibleNormalPart.isEmpty()) {
|
||||
needVisibleFull += !needVisibleFull.isEmpty() ? " " : "";
|
||||
needVisibleFull += needVisibleNormalPart;
|
||||
}
|
||||
String mesPrefix = needVisibleFull + ": ";
|
||||
String mesPostfix = " in " + originalLog;
|
||||
|
||||
// simple check
|
||||
Assert.assertTrue(mesPrefix + "can't find color part" + mesPostfix, originalLog.contains(needVisibleColorPart));
|
||||
Assert.assertTrue(mesPrefix + "can't find normal part" + mesPostfix, originalLog.contains(needVisibleNormalPart));
|
||||
Assert.assertTrue(mesPrefix + "can't find id" + mesPostfix, originalLog.contains(needId));
|
||||
|
||||
// html check
|
||||
Element html = Jsoup.parse(originalLog);
|
||||
Assert.assertEquals(mesPrefix + "can't find full text" + mesPostfix, needVisibleFull, html.text());
|
||||
Element htmlFont = html.getElementsByTag("font").stream().findFirst().orElse(null);
|
||||
Assert.assertNotNull(mesPrefix + "can't find tag [font]" + mesPostfix, htmlFont);
|
||||
Assert.assertNotEquals(mesPrefix + "can't find attribute [color]" + mesPostfix, "", htmlFont.attr("color"));
|
||||
Assert.assertEquals(mesPrefix + "can't find attribute [object_id]" + mesPostfix, needId, htmlFont.attr("object_id"));
|
||||
|
||||
// improved log from client (with href and popup support)
|
||||
String popupLog = GameLog.injectPopupSupport(originalLog);
|
||||
html = Jsoup.parse(popupLog);
|
||||
Assert.assertEquals(mesPrefix + "injected, can't find full text" + mesPostfix, needVisibleFull, html.text());
|
||||
// href
|
||||
Element htmlA = html.getElementsByTag("a").stream().findFirst().orElse(null);
|
||||
Assert.assertNotNull(mesPrefix + "injected, can't find tag [a]" + mesPostfix, htmlA);
|
||||
Assert.assertTrue(mesPrefix + "injected, can't find attribute [href]" + mesPostfix, htmlA.attr("href").startsWith("#"));
|
||||
Assert.assertEquals(mesPrefix + "injected, popup tag [a] must contains colored part only" + mesPostfix, needVisibleColorPart, htmlA.text());
|
||||
// object
|
||||
htmlFont = html.getElementsByTag("font").stream().findFirst().orElse(null);
|
||||
Assert.assertNotNull(mesPrefix + "injected, can't find tag [font]" + mesPostfix, htmlFont);
|
||||
Assert.assertNotEquals(mesPrefix + "can't find attribute [color]" + mesPostfix, "", htmlFont.attr("color"));
|
||||
Assert.assertEquals(mesPrefix + "can't find attribute [object_id]" + mesPostfix, needId, htmlFont.attr("object_id"));
|
||||
}
|
||||
|
||||
private void assertObjectSupport(MageObject object) {
|
||||
String shortId = String.format("[%s]", object.getId().toString().substring(0, 3));
|
||||
|
||||
// original mode with both color and normal parts (name + id)
|
||||
String log = GameLog.getColoredObjectIdName(object, null);
|
||||
assertObjectHtmlLog(
|
||||
log,
|
||||
object.getName(),
|
||||
shortId,
|
||||
object.getId().toString()
|
||||
);
|
||||
|
||||
// custom mode with both color and normal parts
|
||||
String customName = "custom" + shortId + "name";
|
||||
String customPart = "xxx";
|
||||
log = GameLog.getColoredObjectIdName(object.getColor(currentGame), object.getId(), customName, customPart, null);
|
||||
assertObjectHtmlLog(log, customName, customPart, object.getId().toString());
|
||||
|
||||
// custom mode with colored part only
|
||||
customName = "custom" + shortId + "name";
|
||||
customPart = "";
|
||||
log = GameLog.getColoredObjectIdName(object.getColor(currentGame), object.getId(), customName, customPart, null);
|
||||
assertObjectHtmlLog(log, customName, customPart, object.getId().toString());
|
||||
|
||||
// custom mode with normal part only (popup will not work in GUI due empty a-href part)
|
||||
customName = "";
|
||||
customPart = "xxx";
|
||||
log = GameLog.getColoredObjectIdName(object.getColor(currentGame), object.getId(), customName, customPart, null);
|
||||
assertObjectHtmlLog(log, customName, customPart, object.getId().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ObjectNamesInHtml() {
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.HAND, playerA, "Grizzly Bears"); // card
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain"); // permanent
|
||||
addCard(Zone.COMMAND, playerA, "Soldier of Fortune"); // commander
|
||||
// diff names
|
||||
addCustomCardWithAbility("name normal", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("123", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("special \" name 1", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("\"special name 2", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("special name 3\"", playerA, FlyingAbility.getInstance());
|
||||
addCustomCardWithAbility("\"special name 4\"", playerA, FlyingAbility.getInstance());
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.DECLARE_ATTACKERS);
|
||||
execute();
|
||||
|
||||
// colleat all possible objects and test logs with it
|
||||
List<MageObject> sampleObjects = new ArrayList<>();
|
||||
sampleObjects.addAll(currentGame.getBattlefield().getAllPermanents());
|
||||
sampleObjects.addAll(playerA.getHand().getCards(currentGame));
|
||||
sampleObjects.addAll(currentGame.getCommandersIds(playerA, CommanderCardType.ANY, false)
|
||||
.stream()
|
||||
.map(c -> currentGame.getObject(c))
|
||||
.collect(Collectors.toList()));
|
||||
Assert.assertEquals(3 + 7 + 1, sampleObjects.size()); // defaul commander game already contains +1 commander
|
||||
|
||||
sampleObjects.forEach(this::assertObjectSupport);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue