Skip to content

Commit 49843bd

Browse files
authored
Martial ar bonust in weapon list (#66)
* Add Martial Arts modifier to weapons tables
1 parent 64ef11e commit 49843bd

16 files changed

Lines changed: 115 additions & 32 deletions

File tree

JSA-inch.pdf

351 Bytes
Binary file not shown.

app/src/main/java/de/twonirwana/infinity/ExportArmyCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ public static void main(String[] args) {
2727
.flatMap(k -> al.getCombatGroups().get(k).stream())
2828
.toList();
2929

30-
new HtmlPrinter().printCardForArmyCode(armyListOptions, List.of(), al.getSectorial(), fileName, armyCode, useInch, Set.of(Weapon.Type.WEAPON, Weapon.Type.EQUIPMENT, Weapon.Type.SKILL, Weapon.Type.TURRET), true, false, HtmlPrinter.Template.a7_image);
30+
new HtmlPrinter().printCardForArmyCode(armyListOptions, List.of(), db.getAllMartialArtLevels(), al.getSectorial(), fileName, armyCode, useInch, Set.of(Weapon.Type.WEAPON, Weapon.Type.EQUIPMENT, Weapon.Type.SKILL, Weapon.Type.TURRET), true, false, HtmlPrinter.Template.a7_image);
3131
}
3232
}

app/src/main/java/de/twonirwana/infinity/HtmlPrinter.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ public HtmlPrinter() {
107107

108108
public void printCardForArmyCode(List<UnitOption> unitOptions,
109109
List<HackingProgram> allHackingPrograms,
110+
List<MartialArtLevel> allMartialArtLevels,
110111
Sectorial sectorial,
111112
String fileName,
112113
String armyCode,
@@ -115,14 +116,14 @@ public void printCardForArmyCode(List<UnitOption> unitOptions,
115116
boolean showImage,
116117
boolean showHackingPrograms,
117118
Template template) {
118-
writeCards(unitOptions, allHackingPrograms, fileName, armyCode, sectorial, UNIT_IMAGE_FOLDER, CUSTOM_UNIT_IMAGE_FOLDER, UNIT_LOGOS_FOLDER, CARD_FOLDER, useInch, showWeaponOfType, showImage, showHackingPrograms, template);
119+
writeCards(unitOptions, allHackingPrograms, allMartialArtLevels, fileName, armyCode, sectorial, UNIT_IMAGE_FOLDER, CUSTOM_UNIT_IMAGE_FOLDER, UNIT_LOGOS_FOLDER, CARD_FOLDER, useInch, showWeaponOfType, showImage, showHackingPrograms, template);
119120
}
120121

121122
public void printAll(Database db, boolean useInch, Template template) {
122123
db.getAllSectorials().stream()
123124
.filter(s -> !s.isDiscontinued())
124125
.flatMap(s -> db.getAllUnitsForSectorialWithoutMercs(s).stream())
125-
.forEach(u -> writeToFile(u, UNIT_IMAGE_FOLDER, CUSTOM_UNIT_IMAGE_FOLDER, UNIT_LOGOS_FOLDER, "all/" + u.getSectorial().getSlug(), useInch, template));
126+
.forEach(u -> writeToFile(u, db.getAllMartialArtLevels(), UNIT_IMAGE_FOLDER, CUSTOM_UNIT_IMAGE_FOLDER, UNIT_LOGOS_FOLDER, "all/" + u.getSectorial().getSlug(), useInch, template));
126127
}
127128

128129
private void copyFile(String fileName, String sourcePath, String outPath) {
@@ -199,6 +200,8 @@ private void copyCustomUnitImages(UnitOption option, String unitImagePath, Strin
199200
}
200201

201202
public void writeToFile(UnitOption unitOption,
203+
List<MartialArtLevel> allMartialArtLevels,
204+
202205
String unitImagePath,
203206
String customUnitImagePath,
204207
String logoImagePath,
@@ -208,6 +211,7 @@ public void writeToFile(UnitOption unitOption,
208211
String fileName = "%s_%s".formatted(unitOption.getCombinedId(), unitOption.getSlug());
209212
writeCards(List.of(unitOption),
210213
List.of(),
214+
allMartialArtLevels,
211215
fileName,
212216
"-",
213217
unitOption.getSectorial(),
@@ -224,6 +228,7 @@ public void writeToFile(UnitOption unitOption,
224228

225229
public void writeCards(List<UnitOption> unitOptions,
226230
List<HackingProgram> allHackingPrograms,
231+
List<MartialArtLevel> allMartialArtLevels,
227232
String fileName,
228233
String armyCode,
229234
Sectorial sectorial,
@@ -260,7 +265,7 @@ public void writeCards(List<UnitOption> unitOptions,
260265
String headerColor = HEADER_TEXT_COLOR.getOrDefault(sectorial.getParentId() - 1, "white");
261266

262267
List<UnitPrintCard> unitPrintCards = unitOptions.stream()
263-
.flatMap(u -> UnitPrintCard.fromUnitOption(u, useInch, showWeaponOfType, showImage).stream())
268+
.flatMap(u -> UnitPrintCard.fromUnitOption(u, useInch, showWeaponOfType, showImage, allMartialArtLevels).stream())
264269
.toList();
265270

266271
List<PrintHackingProgram> usedHackingPrograms = showHackingPrograms ? getUsedHackingPrograms(unitOptions, allHackingPrograms) : List.of();

app/src/main/java/de/twonirwana/infinity/PrintUtils.java

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.common.base.Joiner;
44
import de.twonirwana.infinity.unit.api.ExtraValue;
5+
import de.twonirwana.infinity.unit.api.Skill;
56
import de.twonirwana.infinity.unit.api.TrooperProfile;
67
import de.twonirwana.infinity.unit.api.Weapon;
78

@@ -12,6 +13,8 @@
1213
import java.util.stream.Stream;
1314

1415
public class PrintUtils {
16+
public static final String CC_ATTACK_SKILL_NAME = "CC Attack";
17+
public static final String BS_ATTACK_SKILL_NAME = "BS Attack";
1518
private static final Pattern PS_EXTRA_REGEX = Pattern.compile("PS=(\\d)");
1619
private static final Pattern BURST_EXTRA_REGEX = Pattern.compile("\\+(\\d)B");
1720
private static final Pattern SPECIAL_DIE_EXTRA_REGEX = Pattern.compile("\\+(\\d)SD");
@@ -23,6 +26,7 @@ public class PrintUtils {
2326
private static final String MINUS_3_MODI = "-3";
2427
private static final String MINUS_6_MODI = "-6";
2528
private static final String XVISOR_NAME = "X Visor";
29+
private static final String MARTIAL_ARTS_SKILL_NAME_PREFIX = "Martial Arts L";
2630

2731
public static String getRangeHeader(boolean useInch) {
2832
return "Range %s".formatted(useInch ? "″" : "cm");
@@ -48,6 +52,20 @@ public static String prettyWeaponName(Weapon weapon, boolean useInch) {
4852
return out;
4953
}
5054

55+
public static boolean skillIsMartialArt(Skill skill) {
56+
return skill.getName().startsWith(MARTIAL_ARTS_SKILL_NAME_PREFIX);
57+
}
58+
59+
public static Optional<MartialArtLevel> getMartialArtLevel(TrooperProfile profile, Map<String, MartialArtLevel> allMartialArtLevels) {
60+
return profile.getSkills().stream()
61+
.filter(PrintUtils::skillIsMartialArt)
62+
.map(Skill::getName)
63+
.map(s -> s.replace(MARTIAL_ARTS_SKILL_NAME_PREFIX, ""))
64+
.map(allMartialArtLevels::get)
65+
.filter(Objects::nonNull)
66+
.findFirst();
67+
}
68+
5169
private static String getExtraString(Weapon weapon, boolean useInch) {
5270
return weapon.getExtras().stream()
5371
.filter(e -> toPsExtra(e).isEmpty())
@@ -57,21 +75,18 @@ private static String getExtraString(Weapon weapon, boolean useInch) {
5775
.collect(Collectors.joining(", "));
5876
}
5977

60-
public static final String CC_ATTACK_SKILL_NAME = "CC Attack";
61-
public static final String BS_ATTACK_SKILL_NAME = "BS Attack";
62-
6378
private static String getWeaponSkill(Weapon weapon) {
64-
return Weapon.Skill.CC == weapon.getSkill() ? CC_ATTACK_SKILL_NAME: BS_ATTACK_SKILL_NAME;
79+
return Weapon.Skill.CC == weapon.getSkill() ? CC_ATTACK_SKILL_NAME : BS_ATTACK_SKILL_NAME;
6580
}
6681

67-
public static String getWeaponBurstWithExtra(TrooperProfile trooperProfile, Weapon weapon) {
82+
public static String getWeaponBurstWithExtra(UnitPrintCard unitPrintCard, Weapon weapon) {
6883
if (weapon.getBurst() == null) {
6984
return "";
7085
}
7186
String weaponSkill = getWeaponSkill(weapon);
7287
List<ExtraValue> weaponAndSkillExtra = Stream.concat(
7388
weapon.getExtras().stream(),
74-
trooperProfile.getSkills().stream()
89+
unitPrintCard.getProfile().getSkills().stream()
7590
.filter(s -> s.getName().equals(weaponSkill))
7691
.filter(s -> isWeaponOrHasBsProperty(weapon)) //only weapon or bs trait get skill extra
7792
.flatMap(s -> s.getExtras().stream())
@@ -94,7 +109,15 @@ public static String getWeaponBurstWithExtra(TrooperProfile trooperProfile, Weap
94109
.map(Optional::get)
95110
.map("+%sSD"::formatted)
96111
.toList();
97-
return weapon.getBurst() + Joiner.on("").join(burstExtra) + Joiner.on("").join(sdExtra);
112+
113+
String maBurstBonus = "";
114+
if (weapon.getSkill() == Weapon.Skill.CC
115+
&& unitPrintCard.getMartialArtLevels() != null
116+
&& !"0".equals(unitPrintCard.getMartialArtLevels().getBurst())) {
117+
maBurstBonus = unitPrintCard.getMartialArtLevels().getBurst();
118+
}
119+
120+
return weapon.getBurst() + Joiner.on("").join(burstExtra) + Joiner.on("").join(sdExtra) + maBurstBonus;
98121
}
99122

100123
public static String getWeaponPsWithExtra(TrooperProfile trooperProfile, Weapon weapon) {
@@ -219,7 +242,7 @@ static Optional<String> toBurstExtra(ExtraValue extraValue) {
219242
return Optional.empty();
220243
}
221244

222-
static Optional<String> toSpecialDieExtra(ExtraValue extraValue) {
245+
static Optional<String> toSpecialDieExtra(ExtraValue extraValue) {
223246
if (extraValue.getText() == null) {
224247
return Optional.empty();
225248
}

app/src/main/java/de/twonirwana/infinity/UnitPrintCard.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Value;
66

77
import java.util.*;
8+
import java.util.function.Function;
89
import java.util.stream.Collectors;
910
import java.util.stream.IntStream;
1011
import java.util.stream.Stream;
@@ -18,13 +19,23 @@ public class UnitPrintCard {
1819
boolean useInch;
1920
Set<Weapon.Type> showWeaponOfType;
2021
boolean showImage;
22+
MartialArtLevel martialArtLevels;
2123

2224
public static List<UnitPrintCard> fromUnitOption(UnitOption unitOption,
2325
boolean useInch,
2426
Set<Weapon.Type> showWeaponOfType,
25-
boolean showImage) {
27+
boolean showImage,
28+
List<MartialArtLevel> allMartialArtLevels) {
29+
Map<String, MartialArtLevel> martialArtLevelMap = allMartialArtLevels.stream()
30+
.collect(Collectors.toMap(MartialArtLevel::getName, Function.identity()));
2631
return unitOption.getAllTrooper().stream()
27-
.flatMap(t -> t.getProfiles().stream().map(p -> new UnitPrintCard(unitOption, t, p, useInch, showWeaponOfType, showImage)))
32+
.flatMap(t -> t.getProfiles().stream().map(p -> new UnitPrintCard(unitOption,
33+
t,
34+
p,
35+
useInch,
36+
showWeaponOfType,
37+
showImage,
38+
PrintUtils.getMartialArtLevel(p, martialArtLevelMap).orElse(null))))
2839
.toList();
2940
}
3041

@@ -48,6 +59,7 @@ private static boolean notAppliedToWeapon(Skill skill) {
4859
if (PrintUtils.toSrExtra(extraValue).isPresent()) {
4960
return false;
5061
}
62+
//martial arts is still shown
5163
return true;
5264
}
5365

@@ -150,8 +162,15 @@ public List<String> getIconFileNames() {
150162

151163
public String prettySkills() {
152164
return profile.getSkills().stream()
153-
.filter(UnitPrintCard::notAppliedToWeapon)
154-
.map(this::getSkillNameAndExtra).collect(Collectors.joining(", "));
165+
.filter(UnitPrintCard::notAppliedToWeapon).map(this::getSkillNameAndExtra)
166+
.collect(Collectors.joining(", "));
167+
}
168+
169+
public String getMartialArtsBonus() {
170+
if (martialArtLevels == null) {
171+
return "CC";
172+
}
173+
return "CC [MA Att./Opp: %s/%s]".formatted(martialArtLevels.getAttackerModi(), martialArtLevels.getOpponentModi());
155174
}
156175

157176
public String prettyEquipments() {

app/src/main/java/de/twonirwana/infinity/util/UnitNameCheck.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import de.twonirwana.infinity.UnitPrintCard;
55
import de.twonirwana.infinity.unit.api.Weapon;
66

7+
import java.util.List;
78
import java.util.Set;
89

910
public class UnitNameCheck {
@@ -26,7 +27,7 @@ public static void main(final String[] args) {
2627

2728

2829
new DatabaseImp().getAllUnitOptions().stream()
29-
.flatMap(u -> UnitPrintCard.fromUnitOption(u, true, Set.of(Weapon.Type.WEAPON, Weapon.Type.EQUIPMENT, Weapon.Type.SKILL), true).stream())
30+
.flatMap(u -> UnitPrintCard.fromUnitOption(u, true, Set.of(Weapon.Type.WEAPON, Weapon.Type.EQUIPMENT, Weapon.Type.SKILL), true, List.of()).stream())
3031
.map(c -> {
3132
String oldName = c.getProfile().getName();
3233
String newName = c.getUnitName();

app/src/main/resources/templates/CardBW.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ <h3>Weapons</h3>
239239
</div>
240240
</td>
241241
<td th:text="${printUtils.getWeaponPsWithExtra(unitPrintCard.getProfile(), weapon)}"></td>
242-
<td th:text="${printUtils.getWeaponBurstWithExtra(unitPrintCard.getProfile(), weapon)}"></td>
242+
<td th:text="${printUtils.getWeaponBurstWithExtra(unitPrintCard, weapon)}"></td>
243243
<td th:text="${weapon.ammunition != null ? weapon.ammunition.name : ''}"></td>
244244
</tr>
245245

app/src/main/resources/templates/ColorAndOptionalImageCard.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,13 @@ <h2 class="unit-header-title">
244244
</thead>
245245
<tbody>
246246
<tr th:each="weapon : ${unitPrintCard.getWeapons()}">
247-
<td th:text="${printUtils.prettyWeaponName(weapon, unitPrintCard.isUseInch())}"></td>
247+
<td style="white-space: pre" th:text="${printUtils.prettyWeaponName(weapon, unitPrintCard.isUseInch())}"></td>
248248
<th:block th:if="${printUtils.getRangeTemplate(weapon) != null}">
249249
<td colspan="7" th:text="${printUtils.getRangeTemplate(weapon)}"></td>
250250
</th:block>
251251

252252
<th:block th:if="${printUtils.isCC(weapon)}">
253-
<td colspan="7">CC</td>
253+
<td colspan="7" th:text="${unitPrintCard.getMartialArtsBonus()}">CC</td>
254254
</th:block>
255255

256256
<th:block th:if="${printUtils.getRangeTemplate(weapon) == null && !printUtils.isCC(weapon)}">
@@ -271,7 +271,7 @@ <h2 class="unit-header-title">
271271
</th:block>
272272

273273
<td th:text="${printUtils.getWeaponPsWithExtra(unitPrintCard.getProfile(), weapon)}"></td>
274-
<td th:text="${printUtils.getWeaponBurstWithExtra(unitPrintCard.getProfile(), weapon)}"></td>
274+
<td th:text="${printUtils.getWeaponBurstWithExtra(unitPrintCard, weapon)}"></td>
275275
<td th:text="${weapon.ammunition != null ? weapon.ammunition.name : ''}"></td>
276276
<td th:text="${printUtils.getWeaponPropertiesString(weapon)}"
277277
th:style="' white-space: normal; font-size: ' + ${secondaryFontSize}"></td>

app/src/test/java/de/twonirwana/infinity/HtmlPrinterTest.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ public class HtmlPrinterTest {
2020
Set.of(Weapon.Type.WEAPON),
2121
Set.of(Weapon.Type.WEAPON, Weapon.Type.EQUIPMENT, Weapon.Type.SKILL, Weapon.Type.TURRET));
2222
HtmlPrinter underTest;
23-
String fileName = "testFile";
23+
String fileName;
2424
Sectorial sectorial;
2525
UnitOption unitOption;
2626
HackingProgram hackingProgram;
27+
List<MartialArtLevel> martialArtLevels;
2728

2829
private static Stream<Arguments> generateTestData() {
2930
List<Arguments> testData = new ArrayList<>();
@@ -46,10 +47,12 @@ void setup() {
4647
underTest = new HtmlPrinter();
4748
sectorial = new Sectorial(1, 1, "name", "slug", false, "logo.png");
4849

49-
List<Skill> skills = List.of(new Skill(1, "skill", "wiki", 1, List.of(
50-
new ExtraValue(2, "extra", ExtraValue.Type.Text, null),
51-
new ExtraValue(3, "extra distance", ExtraValue.Type.Distance, 10f))
52-
));
50+
List<Skill> skills = List.of(
51+
new Skill(1, "skill", "wiki", 1, List.of(
52+
new ExtraValue(2, "extra", ExtraValue.Type.Text, null),
53+
new ExtraValue(3, "extra distance", ExtraValue.Type.Distance, 10f))
54+
),
55+
new Skill(2, "Martial Arts L3", "wiki", 1, List.of()));
5356
List<Weapon> weapons = List.of(
5457
new Weapon(4, Weapon.Skill.BS, Weapon.Type.WEAPON, "weapon name", "mode", "wiki", new Ammunition(4, "ammo", "wiki"), "3", "7", "saving", "savingNum", List.of("property"), "+3", "+3", "0", "-3", "-3", "-6", "+6", "profile", 2, List.of(
5558
new ExtraValue(1, "PS=6", ExtraValue.Type.Text, null),
@@ -99,14 +102,17 @@ void setup() {
99102
));
100103
TrooperProfile trooperProfile = new TrooperProfile(sectorial, 1, 2, 3, 4, "name", List.of(10, 10), 10, 10, 10, 10, 3, 3, 2, false, 2, "notes", "type", 3, weapons, skills, equipments, List.of("char1", "char2"), "logo.png", List.of("image.png"), List.of(new Order(Order.Type.REGULAR, 0, 1)));
101104
Trooper trooper = new Trooper(sectorial, 1, 2, 3, "optionName", "category", "0.5", 20, List.of(trooperProfile), List.of(), "note", "groupNote");
105+
martialArtLevels = List.of(new MartialArtLevel("-3", "-", "+3", "3", "+1SD"));
106+
102107
unitOption = new UnitOption(sectorial, 1, 2, 3, "isc", "iscAbbr", "unitName", "optionName", "slug", "unitOptionName",
103108
trooper, List.of(), 20, "0.5", "note", false);
104109
}
105110

106111
@ParameterizedTest
107112
@MethodSource("generateTestData")
108113
void testHtml(boolean useInch, Set<Weapon.Type> weaponOption, boolean showImage, boolean showHackingProgram, HtmlPrinter.Template template) {
109-
underTest.writeCards(List.of(unitOption), List.of(), fileName, "", sectorial, "", "", "", "", useInch, weaponOption, showImage, showHackingProgram, template);
114+
fileName = "testFile_" + System.currentTimeMillis();
115+
underTest.writeCards(List.of(unitOption), List.of(), martialArtLevels, fileName, "", sectorial, "", "", "", "", useInch, weaponOption, showImage, showHackingProgram, template);
110116

111117
assertThat(new File("out/html/" + fileName + ".html")).exists();
112118
}

app/src/test/java/de/twonirwana/infinity/ManualHtmlPrinterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void testHtml(String armyCode, String expectedUnitIds, boolean useInch, Set<Weap
126126
.flatMap(k -> al.getCombatGroups().get(k).stream())
127127
.toList();
128128

129-
underTest.printCardForArmyCode(armyListOptions, db.getAllHackingPrograms(), al.getSectorial(), fileName, armyCode, useInch, weaponOption, showImage, showHackingPrograms, template);
129+
underTest.printCardForArmyCode(armyListOptions, db.getAllHackingPrograms(), db.getAllMartialArtLevels(), al.getSectorial(), fileName, armyCode, useInch, weaponOption, showImage, showHackingPrograms, template);
130130

131131
Path result = Paths.get("out/html/card/" + fileName + ".html");
132132
assertThat(result).exists();

0 commit comments

Comments
 (0)