Model attack and defence profiles

This commit is contained in:
Loïc Prieto 2025-06-15 18:27:35 +02:00
parent c41ac72f28
commit df1f543e6d
15 changed files with 237 additions and 10 deletions

27
pom.xml
View file

@ -15,6 +15,14 @@
</properties>
<dependencies>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- Or latest -->
<scope>provided</scope>
</dependency>
<!-- JavaFX modules -->
<dependency>
<groupId>org.openjfx</groupId>
@ -23,4 +31,23 @@
</dependency>
</dependencies>
<build>
<plugins>
<!-- Lombok annotation processor (optional but recommended for IDE integration) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,28 @@
package ninja.thefirearchmage.games.fourtykcalculator;
import java.util.List;
import java.util.Optional;
public class AttackScenario {
private List<Weapon> weapons;
private Optional<Reroll> hitReroll;
private Optional<Reroll> woundReroll;
private Optional<Reroll> damageReroll;
private boolean unmodifiableHit;
private boolean attackerWasStationary;
private boolean attackerCharged;
private boolean attackerInRapidFireRange;
private DefensiveProfile defensiveProfile;
private Optional<Reroll> normalSaveReroll;
private boolean hasHitPenalty;
private boolean hasWoundPenalty;
private boolean isInCover;
private boolean forceWoundsOnFoursIfLower;
private int damageReduction;
public void resolveAttack() {
// Attack step
}
}

View file

@ -0,0 +1,24 @@
package ninja.thefirearchmage.games.fourtykcalculator;
import lombok.Getter;
import java.util.Optional;
@Getter
public class DefensiveProfile {
private final int toughness;
private final int normalSave;
private final Optional<InvulnerableSave> invulnerableSave;
private final Optional<FeelNoPainEffect> feelNoPain;
public DefensiveProfile(int toughness, int normalSave) {
this(toughness, normalSave, Optional.empty(), Optional.empty());
}
public DefensiveProfile(int toughness, int normalSave, Optional<InvulnerableSave> invulnerableSave, Optional<FeelNoPainEffect> feelNoPain) {
this.toughness = toughness;
this.normalSave = normalSave;
this.invulnerableSave = invulnerableSave;
this.feelNoPain = feelNoPain;
}
}

View file

@ -0,0 +1,7 @@
package ninja.thefirearchmage.games.fourtykcalculator;
public class FeelNoPainEffect {
private int rollValue;
private FeelNoPainType type;
}

View file

@ -0,0 +1,7 @@
package ninja.thefirearchmage.games.fourtykcalculator;
public enum FeelNoPainType {
ALL,
MORTAL_WOUNDS,
PSYCHIC;
}

View file

@ -20,16 +20,16 @@ public class FourtyKCalculatorApp extends Application {
Button calculateBtn = new Button("Calculate");
calculateBtn.setOnAction(e -> {
List<Target> targets = Arrays.asList(
new Target("Rhino", 9, 3, null, 10),
new Target("Lehman Russ", 11, 2, null, 13),
new Target("Redemptor Dread", 10, 3, 5, 12),
new Target("Knight Paladin", 13, 2, 5, 22),
new Target("Plagueburst Crawler", 12, 3, 4, 12)
List<DefensiveProfile> targets = Arrays.asList(
new DefensiveProfile("Rhino", 9, 3, null, 10),
new DefensiveProfile("Lehman Russ", 11, 2, null, 13),
new DefensiveProfile("Redemptor Dread", 10, 3, 5, 12),
new DefensiveProfile("Knight Paladin", 13, 2, 5, 22),
new DefensiveProfile("Plagueburst Crawler", 12, 3, 4, 12)
);
StringBuilder sb = new StringBuilder();
for (Target target : targets) {
for (DefensiveProfile target : targets) {
sb.append(calculate(target, 3, true, true, true, "melta"));
sb.append("\n");
}

View file

@ -0,0 +1,18 @@
package ninja.thefirearchmage.games.fourtykcalculator;
import lombok.Getter;
@Getter
public class InvulnerableSave {
private final int rollValue;
private final InvulnerableType type;
public InvulnerableSave(int rollValue) {
this(rollValue, InvulnerableType.ALL);
}
public InvulnerableSave(int rollValue, InvulnerableType type) {
this.rollValue = rollValue;
this.type = type;
}
}

View file

@ -0,0 +1,10 @@
package ninja.thefirearchmage.games.fourtykcalculator;
/**
* To which attack type the invulnerability save applies.
*/
public enum InvulnerableType {
ALL,
RANGED,
MELEE;
}

View file

@ -2,6 +2,6 @@ package ninja.thefirearchmage.games.fourtykcalculator;
public class Main {
public static void main(String[] args) {
System.out.printf("Hello and welcome!");
}
}

View file

@ -0,0 +1,7 @@
package ninja.thefirearchmage.games.fourtykcalculator;
import java.util.Set;
public class Reroll {
private Set<Integer> rerollableValues;
}

View file

@ -5,7 +5,9 @@ import java.util.Optional;
public class Weapon {
private int strength;
private int ap;
private double averageDamage;
private int attacks;
private WeaponDamage averageDamage;
private WeaponRangeType rangeType;
private int hitValue;
private boolean hasLethalHits;
private Optional<Integer> sustainedHits;
@ -18,5 +20,8 @@ public class Weapon {
private boolean hasHeavy;
private boolean hasBlast;
private boolean hasLance;
private boolean ignoresCover;
private Optional<Integer> melta;
}

View file

@ -0,0 +1,27 @@
package ninja.thefirearchmage.games.fourtykcalculator;
import lombok.Getter;
import java.util.Optional;
@Getter
public class WeaponDamage {
private final Optional<Integer> diceType;
private final Optional<Integer> numberOfDices;
private final int flatDamage;
public WeaponDamage(int flatDamage) {
this(Optional.empty(), Optional.empty(), flatDamage);
}
public WeaponDamage(int diceType, int numberOfDices) {
this(Optional.of(diceType), Optional.of(numberOfDices), 0);
}
public WeaponDamage(int diceType, int numberOfDices, int extraDamage) {
this(Optional.of(diceType), Optional.of(numberOfDices), extraDamage);
}
public WeaponDamage(Optional<Integer> diceType, Optional<Integer> numberOfDices, int flatDamage) {
this.diceType = diceType;
this.numberOfDices = numberOfDices;
this.flatDamage = flatDamage;
}
}

View file

@ -0,0 +1,6 @@
package ninja.thefirearchmage.games.fourtykcalculator;
public enum WeaponRangeType {
MELEE,
RANGED;
}

View file

@ -0,0 +1,30 @@
- intercessor:
name: Intercessor
toughness: 4
save: 3
- sm_terminator:
name: Space Marine Terminator
toughness: 5
save: 2
invulnerability:
save: 4
type: ALL
- sm_rhino:
name: Space Marine Rhino
toughness: 9
save: 3
- impulsor:
name: Impulsor
toughness: 9
save: 3
- land_raider:
name: Space Marine Land Raider
toughness: 12
save: 2
- questoris_knight:
name: Questoris Class Knight
toughness: 12
save: 3
invulnerability:
save: 5
type: RANGED

View file

@ -1 +1,32 @@
melta:
eradicator_melta_rifle:
name: Melta Rifle (Eradicator)
attacks: 1
range_type: RANGED
damage:
dice_type: 6
number_of_dices: 1
melta: 2
ap: -4
toHit: 3
strength: 9
isHeavy: true
eradicator_multi_melta:
name: Multi-Melta (Eradicator)
damage:
dice_type: 6
number_of_dices: 1
attacks: 2
range_type: RANGED
melta: 2
ap: -4
toHit: 4
strength: 9
isHeavy: true
intercessor_bolt_rifle:
name: Bolt Rifle (Intercessor)
attacks: 2
damage: 1
ap: -1
toHit: 3
strength: 4
isHeavy: true