Skip to content

Commit

Permalink
Merge pull request #548 from xpdota/lb-events
Browse files Browse the repository at this point in the history
Implement LB events
  • Loading branch information
xpdota authored Sep 10, 2024
2 parents 34685ff + bc02554 commit cefe70a
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ protected List<CalloutInitialValues> getExpectedCalls() {
call(490260, "Spread Soon", "Spread Soon (7.9)"),
call(503704, "Start West", "Start West"),
call(542545, "Out", "Out (6.2)"),
call(550431, "Northeast safe", "Northeast safe"),
call(550565, "Northeast safe", "Northeast safe"),
call(559650, "Move", "Move (4.7)"),
call(578812, "Raidwide", "Raidwide (3.5)")
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,14 @@ protected List<AmVerificationValues> getExpectedAms() {
clearAll(702351),
// Omega 1st set
clearAll(727298),
mark(755540, IGNORE1, SMN),
mark(755540, IGNORE2, GNB),
mark(755540, ATTACK1, MNK),
mark(755540, ATTACK2, DRK),
mark(755540, ATTACK3, DNC),
mark(755540, ATTACK4, DRG),
mark(755540, BIND1, WHM),
mark(755540, BIND2, SGE),
mark(755496, IGNORE1, SMN),
mark(755496, IGNORE2, GNB),
mark(755496, ATTACK1, MNK),
mark(755496, ATTACK2, DRK),
mark(755496, ATTACK3, DNC),
mark(755496, ATTACK4, DRG),
mark(755496, BIND1, WHM),
mark(755496, BIND2, SGE),
// Omega 2nd set
clearAll(767438),
mark(773205, IGNORE1, DRK),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package gg.xp.xivsupport.events.actlines.events;

import gg.xp.reevent.events.BaseEvent;

import java.io.Serial;

/**
* Represents an LB gauge update.
* <p>
* Please make sure you are handling things correctly when there is no LB available in the duty.
* See {@link #isLbAvailable()}
*/
public class LimitBreakGaugeEvent extends BaseEvent implements HasPrimaryValue {

public static final int PER_BAR = 10_000;
@Serial
private static final long serialVersionUID = -8062227546447193172L;
// total number of bars
private final int totalBars;
// LB amount, each bar is 10000
private final int rawAmount;

public LimitBreakGaugeEvent(int totalBars, int rawAmount) {
this.totalBars = totalBars;
this.rawAmount = rawAmount;
}

/**
* @return The number of possible bars. e.g. 3 bars in a raid. Not affected by how many bars are full.
*/
public int getTotalBars() {
return totalBars;
}

/**
* @return The maximum for {@link #getCurrentRawValue()} as determined by {@link #getTotalBars()}.
*/
public int getMaxRawValue() {
return totalBars * PER_BAR;
}

/**
* @return The raw amount of the LB gauge, as an integer. Each 10,000 increment is one bar.
* @see #PER_BAR
*/
public int getCurrentRawValue() {
return rawAmount;
}

/**
* @return The current LB gauge state as a float. Equivalent to {@link #getCurrentRawValue()} / {@link #PER_BAR} (floating
* point division).
*/
public float getCurrentValue() {
return ((float) rawAmount) / PER_BAR;
}

/**
* @return the number of completely full bars.
*/
public int getFullBars() {
return rawAmount / PER_BAR;
}

/**
* @return whether the LB gauge is empty. If no LB is available in the duty, always returns true.
*/
public boolean isEmpty() {
return rawAmount == 0;
}

/**
* @return whether the LB guage is full. If no LB is available in the duty, always returns true.
*/
public boolean isFull() {
return rawAmount >= getMaxRawValue();
}

/**
* @return whether LB is currently usable, i.e. at least one complete LB bar is full.
*/
public boolean isLbUsable() {
return getFullBars() > 0;
}

/**
* @return whether there is any LB bar whatsoever, regardless of current state. i.e. whether the current duty
* and party size supports LBs.
*/
public boolean isLbAvailable() {
return totalBars > 0;
}

@Override
public String toString() {
return "LimitBreakGaugeEvent{" +
"totalBars=" + totalBars +
", rawAmount=" + rawAmount +
'}';
}

@Override
public String getPrimaryValue() {
if (totalBars > 0) {
int bars = getFullBars();
String barsFmt = bars > 0 ? ("LB" + bars) : "No LB";
return "%s / %s (%s)".formatted(rawAmount, getMaxRawValue(), barsFmt);
}
else {
return "0 / 0 (LB Unavailable)";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package gg.xp.xivsupport.events.actlines.parsers;

import gg.xp.reevent.events.Event;
import gg.xp.xivsupport.events.actlines.events.LimitBreakGaugeEvent;
import gg.xp.xivsupport.events.actlines.events.TetherEvent;
import org.picocontainer.PicoContainer;

import java.time.ZonedDateTime;

@SuppressWarnings("unused")
public class Line36Parser extends AbstractACTLineParser<Line36Parser.Fields> {

public Line36Parser(PicoContainer container) {
super(container, 36, Fields.class);
}

enum Fields {
value, barCount
}

@Override
protected Event convert(FieldMapper<Fields> fields, int lineNumber, ZonedDateTime time) {
return new LimitBreakGaugeEvent(fields.getInt(Fields.barCount), (int) fields.getHex(Fields.value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package gg.xp.xivsupport.events.state.combatstate;

import gg.xp.reevent.scan.Alias;
import gg.xp.reevent.scan.HandleEvents;
import gg.xp.xivsupport.events.actlines.events.LimitBreakGaugeEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Alias("lbState")
public class LimitBreakState {

private static final LimitBreakGaugeEvent DEFAULT = new LimitBreakGaugeEvent(0, 0);
private LimitBreakGaugeEvent lastEvent;

@HandleEvents
public void limitBreak(LimitBreakGaugeEvent event) {
lastEvent = event;
}

public @Nullable LimitBreakGaugeEvent getLastEvent() {
return lastEvent;
}

public @NotNull LimitBreakGaugeEvent getLastEventOrDefault() {
LimitBreakGaugeEvent last = lastEvent;
if (last == null) {
return DEFAULT;
}
return last;
}

}
4 changes: 4 additions & 0 deletions xivsupport/src/main/resources/te_changelog.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<html lang="en">
<body style="margin: 5px 20px 5px 20px">
<h2>September 9, 2024</h2>
<ul>
<li>Support Limit Break Gauge events</li>
</ul>
<h2>September 5, 2024</h2>
<ul>
<li>Improvements to M1S and M4S.</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package gg.xp.xivsupport.events.actlines;

import gg.xp.xivsupport.events.actlines.events.LimitBreakGaugeEvent;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.testng.Assert;
import org.testng.annotations.Test;

public class Line36Test extends AbstractACTLineTest<LimitBreakGaugeEvent> {

public Line36Test() {
super(LimitBreakGaugeEvent.class);
}

/**
* One partial bar
*/
@Test
public void positiveTest1() {
String goodLine = "36|2024-07-30T18:14:21.3130000-05:00|24B8|3|";
LimitBreakGaugeEvent event = expectEvent(goodLine);
Assert.assertEquals(event.getTotalBars(), 3);
Assert.assertEquals(event.getCurrentRawValue(), 0x24B8);
Assert.assertEquals(event.getMaxRawValue(), 30_000);
Assert.assertEquals(event.getFullBars(), 0);
MatcherAssert.assertThat((double) event.getCurrentValue(), Matchers.closeTo(0.94, 0.0001));
Assert.assertEquals(event.getPrimaryValue(), "9400 / 30000 (No LB)");
Assert.assertTrue(event.isLbAvailable());
Assert.assertFalse(event.isLbUsable());
Assert.assertFalse(event.isEmpty());
Assert.assertFalse(event.isFull());
}

/**
* Two bars and change.
*/
@Test
public void positiveTest2() {
String goodLine = "36|2024-07-30T18:17:33.3080000-05:00|5E10|3|";
LimitBreakGaugeEvent event = expectEvent(goodLine);
Assert.assertEquals(event.getTotalBars(), 3);
Assert.assertEquals(event.getCurrentRawValue(), 0x5E10);
Assert.assertEquals(event.getMaxRawValue(), 30_000);
Assert.assertEquals(event.getFullBars(), 2);
MatcherAssert.assertThat((double) event.getCurrentValue(), Matchers.closeTo(2.408, 0.0001));
Assert.assertEquals(event.getPrimaryValue(), "24080 / 30000 (LB2)");
Assert.assertTrue(event.isLbAvailable());
Assert.assertTrue(event.isLbUsable());
Assert.assertFalse(event.isEmpty());
Assert.assertFalse(event.isFull());
}

/**
* Three full bars
*/
@Test
public void positiveTest3() {
String goodLine = "36|2024-07-30T18:18:39.3320000-05:00|7530|3|";
LimitBreakGaugeEvent event = expectEvent(goodLine);
Assert.assertEquals(event.getTotalBars(), 3);
Assert.assertEquals(event.getCurrentRawValue(), 0x7530);
Assert.assertEquals(event.getMaxRawValue(), 30_000);
Assert.assertEquals(event.getFullBars(), 3);
Assert.assertEquals(event.getCurrentValue(), 3.0);
Assert.assertEquals(event.getPrimaryValue(), "30000 / 30000 (LB3)");
Assert.assertTrue(event.isLbAvailable());
Assert.assertTrue(event.isLbUsable());
Assert.assertFalse(event.isEmpty());
Assert.assertTrue(event.isFull());
}

/**
* Empty bars immediately after using LB3.
*/
@Test
public void positiveTest4() {
String goodLine = "36|2024-07-30T18:21:11.4730000-05:00|0000|3|";
LimitBreakGaugeEvent event = expectEvent(goodLine);
Assert.assertEquals(event.getTotalBars(), 3);
Assert.assertEquals(event.getCurrentRawValue(), 0);
Assert.assertEquals(event.getMaxRawValue(), 30_000);
Assert.assertEquals(event.getFullBars(), 0);
Assert.assertEquals(event.getCurrentValue(), 0.0);
Assert.assertEquals(event.getPrimaryValue(), "0 / 30000 (No LB)");
Assert.assertTrue(event.isLbAvailable());
Assert.assertFalse(event.isLbUsable());
Assert.assertTrue(event.isEmpty());
Assert.assertFalse(event.isFull());
}

/**
* No LB bar
*/
@Test
public void positiveTest5() {
String goodLine = "36|2024-09-07T08:28:50.5240000-07:00|0000|0|";
LimitBreakGaugeEvent event = expectEvent(goodLine);
Assert.assertEquals(event.getTotalBars(), 0);
Assert.assertEquals(event.getCurrentRawValue(), 0);
Assert.assertEquals(event.getMaxRawValue(), 0);
Assert.assertEquals(event.getFullBars(), 0);
Assert.assertEquals(event.getCurrentValue(), 0.0);
Assert.assertEquals(event.getPrimaryValue(), "0 / 0 (LB Unavailable)");
Assert.assertFalse(event.isLbAvailable());
Assert.assertFalse(event.isLbUsable());
Assert.assertTrue(event.isEmpty());
Assert.assertTrue(event.isFull());
}

@Test
public void negativeTest() {
assertNoEvent("25|2021-11-06T09:46:46.4900000-07:00|107361AF|Foo Bar|200524E|Item_524E|107361AD|The Target|33C|20000|1B|270A8000|0|0|0|0|0|0|0|0|0|0|0|0|170781|170781|10000|10000|0|1000|-46.33868|20.93576|1.6|-1.167042|170781|170781|10000|10000|0|1000|-46.33868|20.93576|1.6|-1.167042|000BACE5|0|104137929bde2acb55f6b35d58ffb560");
}
}

0 comments on commit cefe70a

Please sign in to comment.