Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ dependencies {
compileOnly 'org.apache.logging.log4j:log4j-api:2.0-beta9'
compileOnly 'org.apache.logging.log4j:log4j-core:2.0-beta9'

testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation 'org.junit.jupiter:junit-jupiter:5.14.2'

library "com.github.MPKMod.MPKNetworkAPI:common:${project.networkApiVersion}"
}

test {
useJUnitPlatform()
}

compileJava.doLast {
var classFile = new File("$temporaryDir${File.separator}classes.txt")
classFile.createNewFile()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.github.kurrycat.mpkmod.events.Event;
import io.github.kurrycat.mpkmod.gui.MPKGuiScreen;
import io.github.kurrycat.mpkmod.gui.infovars.InfoString;
import io.github.kurrycat.mpkmod.ticks.TickInput;
import io.github.kurrycat.mpkmod.util.input.TickInput;
import io.github.kurrycat.mpknetapi.common.network.packet.MPKPacket;

import java.text.SimpleDateFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class Player {
@InfoString.Field
public Blip lastBlip = null;

public TimingInput timingInput = new TimingInput("");
public TimingInput timingInput = TimingInput.stopTick();
public KeyInput keyInput = null;
public ButtonMSList keyMSList = null;
public Vector3D pos = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package io.github.kurrycat.mpkmod.gui.components;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.*;
import io.github.kurrycat.mpkmod.compatibility.MCClasses.Renderer2D;
import io.github.kurrycat.mpkmod.util.JSONPos2D;
import io.github.kurrycat.mpkmod.util.Mouse;
import io.github.kurrycat.mpkmod.util.Vector2D;

@JsonTypeInfo(
use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.PROPERTY
)
public abstract class Component extends ComponentHolder {
public boolean selected = false;
public boolean highlighted = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.github.kurrycat.mpkmod.save;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -30,10 +29,6 @@ public static void registerSerializer() {
module.addDeserializer(Color.class, new ColorDeserializer());

mapper.registerModule(module);
mapper.enableDefaultTyping(
ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE,
JsonTypeInfo.As.PROPERTY
);
mapper.enable(SerializationFeature.INDENT_OUTPUT);

mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.github.kurrycat.mpkmod.ticks;

public enum GroundState {
GROUNDED(false, true),
AIRBORNE(false, false),
JUMPING(true, false);

public final boolean jump, ground;

GroundState(boolean jump, boolean ground) {
this.jump = jump;
this.ground = ground;
}

public static GroundState fromBooleans(boolean jump, boolean ground) {
if (jump && ground)
throw new IllegalArgumentException("Cannot be both jumping and on ground");

if (jump) return JUMPING;
if (ground) return GROUNDED;
return AIRBORNE;
}
}
40 changes: 38 additions & 2 deletions common/src/main/java/io/github/kurrycat/mpkmod/ticks/Timing.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.kurrycat.mpkmod.compatibility.API;
import io.github.kurrycat.mpkmod.util.MathUtil;
import io.github.kurrycat.mpkmod.util.Tuple;
import io.github.kurrycat.mpkmod.util.input.InputPredicateReference;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -13,14 +14,41 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Timing {
public final class Timing {
private final LinkedHashMap<FormatCondition, FormatString> format;
private final TimingEntry[] timingEntries;
private final boolean symmetrical;
private final Timing mirrored;

@JsonCreator
public Timing(@JsonProperty("format") LinkedHashMap<FormatCondition, FormatString> format, @JsonProperty("timingEntries") TimingEntry[] timingEntries) {
public Timing(
@JsonProperty("format")
LinkedHashMap<FormatCondition, FormatString> format,
@JsonProperty("timingEntries")
TimingEntry[] timingEntries,
@JsonProperty("symmetrical")
Boolean symmetrical
) {
if (symmetrical == null) symmetrical = false;

this.format = format;
this.timingEntries = timingEntries;
this.symmetrical = symmetrical;

this.mirrored = this.symmetrical ? makeMirrored() : null;

for (TimingEntry e : timingEntries) {
if (e.inputPredicate instanceof InputPredicateReference)
((InputPredicateReference) e.inputPredicate).setParentTimingEntries(timingEntries);
}
}

public boolean isSymmetrical() {
return symmetrical;
}

public Timing getMirrored() {
return mirrored;
}

public Match match(List<TimingInput> inputList) {
Expand Down Expand Up @@ -53,6 +81,14 @@ private Match startsWithMatch(List<TimingInput> inputList) {
return new Match(getFormatString(vars), vars.size(), inputList.size() - startIndex);
}

private Timing makeMirrored() {
TimingEntry[] mirroredTimingEntries = new TimingEntry[timingEntries.length];
for (int i = 0; i < timingEntries.length; i++) {
mirroredTimingEntries[i] = timingEntries[i].mirrored();
}
return new Timing(format, mirroredTimingEntries, false);
}

private String getFormatString(HashMap<String, TickMS> vars) {
StringBuilder sb = new StringBuilder();
format.forEach((fc, fs) -> {
Expand Down
147 changes: 69 additions & 78 deletions common/src/main/java/io/github/kurrycat/mpkmod/ticks/TimingEntry.java
Original file line number Diff line number Diff line change
@@ -1,114 +1,97 @@
package io.github.kurrycat.mpkmod.ticks;

import com.fasterxml.jackson.annotation.JsonCreator;
import io.github.kurrycat.mpkmod.util.MathUtil;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.github.kurrycat.mpkmod.util.Range;
import io.github.kurrycat.mpkmod.util.Tuple;
import io.github.kurrycat.mpkmod.util.input.InputPredicate;
import io.github.kurrycat.mpkmod.util.input.InputPredicateBase;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class TimingEntry {
private static final String tickCountRegex = "^((((?<diffNumber>\\d+)-)?((?<varName>[a-zA-Z]+)(\\{(?<lowerRange>\\d+)?,(?<upperRange>\\d+)?})?))|(?<rawCount>\\d+))$";
private static final Pattern tickCountPattern = Pattern.compile(tickCountRegex);
private static final String tickInputRegex = "^W?A?S?D?P?N?J?(!?G)?$";
private static final Pattern tickInputPattern = Pattern.compile(tickInputRegex);
public final class TimingEntry {
public final String varName;
public final Range range;

public String timingEntry;
public TimingInput timingInput;

private Integer number;
private String varName;
private Range range;
public final InputPredicateBase inputPredicate;
public final Boolean P, N;
public final GroundState G;

@JsonCreator
public TimingEntry(String timingEntry) {
this.timingEntry = timingEntry;
String[] split = timingEntry.split(":", -1);
if (split.length == 1) {
number = 1;
varName = null;
range = null;
timingInput = new TimingInput(split[0]);
} else if (split.length == 2) {
Matcher matcher = tickCountPattern.matcher(split[0]);
if (!matcher.matches())
throw new IllegalArgumentException(String.format("Invalid tick count: %s", split[0]));

Integer diffNumber = MathUtil.parseInt(matcher.group("diffNumber"), null);
String varName = matcher.group("varName");
Integer lower = MathUtil.parseInt(matcher.group("lowerRange"), null);
Integer upper = MathUtil.parseInt(matcher.group("upperRange"), null);
Integer rawCount = MathUtil.parseInt(matcher.group("rawCount"), null);

number = diffNumber == null ? rawCount : diffNumber;
this.varName = varName;
range = new Range(lower, upper);

timingInput = new TimingInput(split[1]);
} else {
throw new IllegalArgumentException(String.format("More than one : found in timingEntry '%s', expected one", timingEntry));
}
public TimingEntry(
@JsonProperty("var")
String varName,
@JsonProperty("min")
Integer min,
@JsonProperty("max")
Integer max,
@JsonProperty("inputs")
InputPredicateBase inputPredicate,
@JsonProperty("sprint")
Boolean P,
@JsonProperty("sneak")
Boolean N,
@JsonProperty("groundState")
GroundState G
) {
if (min == null && max == null) min = max = 1;
if (min == null || min <= 0) min = 0;
if (max != null && max < min) max = min;

this.varName = varName;
this.range = new Range(min, max);
this.inputPredicate = inputPredicate;
this.P = P;
this.N = N;
this.G = G;
}

public boolean varNameMatches(TimingEntry other) {
return varName != null && other.varName != null && varName.equals(other.varName);
}

private boolean matchesInput(TimingInput timingInput) {
return (
(inputPredicate == null || inputPredicate.matches(timingInput.inputVector)) &&
(P == null || P == timingInput.P) &&
(N == null || N == timingInput.N) &&
(G == null || G == timingInput.G)
);
}

/**
* @param inputList List of {@link TimingInput} instances
* @param startIndex the index it should start matching from
* @param vars HashMap containing all variables for that {@link Timing}. Vars of this TimingEntry are added
* @param repeatedVar if the current var already appeared before
* @param vars HashMap containing all variables for that {@link Timing}. Vars of this TimingEntry are added
* @param repeatedVar if the current var appeared in the previous {@link TimingEntry}
* @return amount of matched inputs or null if no match was found (returns 0 for variable entries with 0 within range)
*/
public Integer matches(List<TimingInput> inputList, int startIndex, HashMap<String, Timing.TickMS> vars, boolean repeatedVar) {
if (number == null && varName == null) return null;
int i = startIndex;

// is variable
if (number == null) {
int i = startIndex;
while (i < inputList.size() && inputList.get(i).equals(timingInput)) i++;
if (inputPredicate instanceof InputPredicate) ((InputPredicate) inputPredicate).resetLastMatch();
while (i < inputList.size() && matchesInput(inputList.get(i))) i++;
int count = range.constrain(i - startIndex);

i -= startIndex;

if (range.includes(i) || range.isAbove(i)) {
if (vars.containsKey(varName) && repeatedVar)
vars.get(varName).tickCount += range.constrain(i);
else vars.put(varName, new Timing.TickMS(range.constrain(i)));

vars.get(varName).ms = getMS(
startIndex + i - vars.get(varName).tickCount,
vars.get(varName).tickCount,
inputList
);

return range.constrain(i);
}
return null;
}
if (range.isValueBelow(i - startIndex)) return null;

int countToMatch = number;
if (varName != null) {
if (!vars.containsKey(varName)) {
throw new IllegalArgumentException(String.format("The variable %s has not been defined in a prior timing input (at %s)", varName, timingEntry));
if (vars.containsKey(varName) && repeatedVar) {
vars.get(varName).tickCount += count;
} else {
countToMatch -= vars.get(varName).tickCount;
vars.put(varName, new Timing.TickMS(count));
}
}

if (inputList.size() == startIndex && number != 0) return null;

int i;
for (i = startIndex; countToMatch > 0; countToMatch--, i++) {
if (i >= inputList.size()) return null;
if (!inputList.get(i).equals(timingInput)) return null;
vars.get(varName).ms = getMS(
i - vars.get(varName).tickCount,
vars.get(varName).tickCount,
inputList
);
}
return i - startIndex;

return count;
}

private Integer getMS(int startIndex, int matchCount, List<TimingInput> inputList) {
Expand All @@ -135,4 +118,12 @@ private Integer getMS(int startIndex, int matchCount, List<TimingInput> inputLis
if (endMS == null) return null;
return endMS.msFrom(startMS);
}

public TimingEntry mirrored() {
InputPredicateBase mirroredInputPredicate = inputPredicate;
if (inputPredicate instanceof InputPredicate)
mirroredInputPredicate = ((InputPredicate) inputPredicate).mirrored();

return new TimingEntry(varName, range.getLower(), range.getUpper(), mirroredInputPredicate, P, N, G);
}
}
Loading
Loading