Gacha rework

Add fallback stripping and C6 stripping
Converting banner definitions from pity vars to lerp arrays
Properly implement rates and pool smoothing
Also move reusable functions to Utils
This commit is contained in:
AnimeGitB
2022-05-06 23:39:45 +09:30
committed by Melledy
parent 3c55aa64eb
commit f83f13204e
5 changed files with 397 additions and 168 deletions

View File

@@ -15,6 +15,8 @@ import emu.grasscutter.Grasscutter;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.slf4j.Logger;
@@ -314,4 +316,68 @@ public final class Utils {
return String.format("%s-%s", locale.getLanguage(), locale.getCountry());
}
/**
* Performs a linear interpolation using a table of fixed points to create an effective piecewise f(x) = y function.
* @param x
* @param xyArray Array of points in [[x0,y0], ... [xN, yN]] format
* @return f(x) = y
*/
public static int lerp(int x, int[][] xyArray) {
try {
if (x <= xyArray[0][0]){ // Clamp to first point
return xyArray[0][1];
} else if (x >= xyArray[xyArray.length-1][0]) { // Clamp to last point
return xyArray[xyArray.length-1][1];
}
// At this point we're guaranteed to have two lerp points, and pity be somewhere between them.
for (int i=0; i < xyArray.length-1; i++) {
if (x == xyArray[i+1][0]) {
return xyArray[i+1][1];
}
if (x < xyArray[i+1][0]) {
// We are between [i] and [i+1], interpolation time!
// Using floats would be slightly cleaner but we can just as easily use ints if we're careful with order of operations.
int position = x - xyArray[i][0];
int fullDist = xyArray[i+1][0] - xyArray[i][0];
int prevValue = xyArray[i][1];
int fullDelta = xyArray[i+1][1] - prevValue;
return prevValue + ( (position * fullDelta) / fullDist );
}
}
} catch (IndexOutOfBoundsException e) {
Grasscutter.getLogger().error("Malformed lerp point array. Must be of form [[x0, y0], ..., [xN, yN]].");
}
return 0;
}
/**
* Checks if an int is in an int[]
* @param key int to look for
* @param array int[] to look in
* @return key in array
*/
public static boolean intInArray(int key, int[] array) {
for (int i : array) {
if (i == key) {
return true;
}
}
return false;
}
/**
* Return a copy of minuend without any elements found in subtrahend.
* @param minuend The array we want elements from
* @param subtrahend The array whose elements we don't want
* @return The array with only the elements we want, in the order that minuend had them
*/
public static int[] setSubtract(int[] minuend, int[] subtrahend) {
IntList temp = new IntArrayList();
for (int i : minuend) {
if (!intInArray(i, subtrahend)) {
temp.add(i);
}
}
return temp.toIntArray();
}
}