Начинающий
- Статус
- Оффлайн
- Регистрация
- 18 Июн 2022
- Сообщения
- 323
- Реакции
- 14
- Выберите загрузчик игры
- OptiFine
- ForgeOptiFine
Нашёл в своём старом проекте, есть как простые stealth-генераторы для int, double, float, так и интересные с разными паттернами. Сам использовал в киллауре для ротаций.
AdvancedRandUtil:
package minecraft.system;
import lombok.experimental.UtilityClass;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@UtilityClass
public class AdvancedRandUtil{
private final SecureRandom baseRandom = new SecureRandom();
private static final int LAYERS = 9;
private static final int[] PRIMES = {0x9E3779B1, 0x85EBCA77, 0xC2B2AE3D};
private static double lastValue = Double.NaN;
private static int counter = 0;
private static double lastVelocity = 0.0; // Добавлено для инерции
private static int fatigueCounter = 0; // Отдельный счетчик для усталости
public int stealthInt(int minLimit, int maxLimit) {
if (minLimit >= maxLimit) return minLimit;
// Инициализация каскада
int[] layers = new int[7];
layers[0] = minLimit + baseRandom.nextInt(maxLimit - minLimit + 1);
// Главный каскад случайности
for (int i = 1; i < layers.length; i++) {
int range = maxLimit - minLimit + 1;
// Динамические параметры для текущего слоя
int noiseFactor = 1 + baseRandom.nextInt(3);
int shiftBits = baseRandom.nextInt(8);
int directionFlag = baseRandom.nextInt(2);
// Генерация шума с расширением диапазона
int expandedRange = range * (2 + noiseFactor);
int noise = baseRandom.nextInt(expandedRange) - (expandedRange / 2);
// Нелинейные преобразования
layers[i] = applyNonLinearTransform(
layers[i - 1],
minLimit,
maxLimit,
noise,
shiftBits,
directionFlag
);
}
// Финальная стабилизация в целевом диапазоне
return stabilize(layers[layers.length - 1], minLimit, maxLimit);
}
private int applyNonLinearTransform(int value, int min, int max, int noise, int shift, int direction) {
// Динамическое изменение значения
int transformed = (value ^ (value << shift)) + noise;
// Обратная связь с предыдущими значениями
transformed = (transformed & 0x5555_5555) | ((transformed & 0xAAAA_AAAA) >>> 1);
// Направленное смещение
if (direction == 0) {
transformed = Integer.rotateLeft(transformed, shift);
} else {
transformed = Integer.rotateRight(transformed, shift);
}
// Псевдо-стабилизация
return (transformed % (max - min + 1)) + min;
}
private int stabilize(int value, int min, int max) {
// Многоэтапная стабилизация
for (int i = 0; i < 3; i++) {
int range = max - min + 1;
int mid = min + range / 2;
// Квадратичное сжатие к центру
int offset = (value - mid) * (value - mid) / range;
value = mid + (value > mid ? -offset : offset);
// Коррекция границ
if (value < min) value += range;
if (value > max) value -= range;
}
// Гарантированное возвращение в диапазон
return Math.min(Math.max(value, min), max);
}
public static double stealthDouble(double min, double max) {
if (min >= max) return min;
long seed = ThreadLocalRandom.current().nextLong();
double value = entropyWave(seed);
for (int i = 0; i < LAYERS; i++) {
value = fractalDistortion(value, min, max, i);
}
return constrain(value, min, max);
}
public static float stealthFloat(float min, float max) {
if (min >= max) return min;
long seed = ThreadLocalRandom.current().nextLong();
float value = (float) entropyWave(seed);
for (int i = 0; i < LAYERS; i++) {
value = (float) fractalDistortion(value, min, max, i);
}
return (float) constrain(value, min, max);
}
private static double entropyWave(long seed) {
long state = seed ^ 0xDEADBEEFFACADE00L;
state = (state ^ (state >>> 30)) * PRIMES[0];
state = (state ^ (state >>> 27)) * PRIMES[1];
state = (state ^ (state >>> 31)) | PRIMES[2];
return Double.longBitsToDouble(state);
}
private static double fractalDistortion(double input, double min, double max, int layer) {
double range = max - min;
long bits = Double.doubleToRawLongBits(input);
// Хаотические преобразования
Random rand = ThreadLocalRandom.current();
bits ^= (bits << (layer * 9 + 5)) | (bits >>> (layer * 7 + 11));
bits = Long.rotateLeft(bits, rand.nextInt(64));
bits += rand.nextLong() ^ PRIMES[layer % PRIMES.length];
bits *= rand.nextBoolean() ? 1.6180339887 : 3.1415926535;
// Фрактальное зашумление
double noise = rand.nextDouble() * range / Math.pow(2, layer);
double result = Double.longBitsToDouble(bits) * noise;
// Нелинейное сжатие
return Math.sin(result * Math.PI) * range * 0.5 + (min + max) * 0.5;
}
private static double constrain(double value, double min, double max) {
// Квантовое ограничение с хаотической коррекцией
if (value >= min && value <= max) return value;
double scaled = Math.abs(value) % (max - min);
return scaled + min - ((int)(scaled / (max - min)) * (max - min));
}
public enum PatternMode {
LINEAR_SMOOTH, // Плавные линейные изменения
GAUSSIAN_CENTERED, // Концентрация в центре диапазона
EDGE_BIASED, // Смещение к краям диапазона
STEPPED, // Ступенчатое изменение значений
CHAOTIC_SMOOTH, // Хаотичные но плавные переходы
//humanaized:
HUMAN_TREMOR, // Мелкая дрожь как у человека
SACCADIC_MOVEMENT, // Скачкообразные движения глаз
MICRO_CORRECTIONS, // Микрокоррекции с возвратом
INERTIA_SMOOTH, // Движение с инерцией
FATIGUE_DRIFT, // Дрейф при усталости
TREMOR_PREDICT,
FATIGURE_ADVANCE,
INTERIA_DECREATE
}
// Double генератор
public static double LegitDouble(double min, double max, PatternMode mode) {
if (min >= max) return min;
double value;
switch (mode) {
case LINEAR_SMOOTH:
value = linearSmooth(min, max);
break;
case GAUSSIAN_CENTERED:
value = gaussianCentered(min, max);
break;
case EDGE_BIASED:
value = edgeBiased(min, max);
break;
case STEPPED:
value = stepped(min, max);
break;
case CHAOTIC_SMOOTH:
value = chaoticSmooth(min, max);
break;
case HUMAN_TREMOR:
value = humanTremor(min, max);
break;
case SACCADIC_MOVEMENT:
value = saccadicMovement(min, max);
break;
case MICRO_CORRECTIONS:
value = microCorrections(min, max);
break;
case INERTIA_SMOOTH:
value = inertiaSmooth(min, max);
break;
case FATIGUE_DRIFT:
value = fatigueDrift(min, max);
break;
case TREMOR_PREDICT:
value = Pred_Tremor(min, max);
break;
case INTERIA_DECREATE:
value = interia2(min, max);
break;
case FATIGURE_ADVANCE:
value = ADVfatigueDrift(min, max);
break;
default:
value = baseRandom.nextDouble() * (max - min) + min;
}
lastValue = value;
counter++;
return value;
}
// Float генератор
public static float LegitFloat(float min, float max, PatternMode mode) {
return (float) LegitDouble(min, max, mode);
}
private static double Pred_Tremor(double min, double max) {
double baseValue = Double.isNaN(lastValue)
? (min + max) / 2.0
: lastValue;
// Псевдо-периодический тремор (8-12 Гц)
double timeFactor = counter * 0.3;
double tremorX = Math.sin(timeFactor * 25.3) * 0.4;
double tremorY = Math.cos(timeFactor * 22.7) * 0.3;
double tremorZ = Math.sin(timeFactor * 18.9) * 0.3;
double tremor = (tremorX + tremorY + tremorZ) / 3.0;
tremor *= 0.03 * (max - min); // Амплитуда 3% от диапазона
// Случайные микро-скачки
if(counter % 15 == 0) {
tremor += baseRandom.nextGaussian() * 0.02 * (max - min);
}
return constrain(baseValue + tremor, min, max);
}
// Режимы работы
private static double linearSmooth(double min, double max) {
if (Double.isNaN(lastValue)) {
return baseRandom.nextDouble() * (max - min) + min;
}
// Плавное изменение с небольшой случайной дельтой
double range = max - min;
double step = range * 0.05 * (baseRandom.nextGaussian() + 0.3);
double newValue = lastValue + step;
// Коррекция при выходе за границы
if (newValue < min || newValue > max) {
double target = min + range * (0.2 + 0.6 * baseRandom.nextDouble());
return target;
}
return newValue;
}
private static double gaussianCentered(double min, double max) {
double center = (min + max) / 2.0;
double range = max - min;
// Генерация с нормальным распределением
double value = center + baseRandom.nextGaussian() * (range / 6.0);
// Периодическая коррекция к центру
if (counter % 5 == 0) {
double offset = (value - center) * 0.7;
value = center + offset;
}
// Гарантия в диапазоне
return Math.max(min, Math.min(max, value));
}
private static double edgeBiased(double min, double max) {
// Случайный выбор края
double targetEdge = baseRandom.nextBoolean() ? min : max;
// Генерация со смещением к краю
double biasStrength = 0.7 + baseRandom.nextDouble() * 0.25;
double value;
if (targetEdge == min) {
value = min + Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
} else {
value = max - Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
}
// Периодические "проверки" центра
if (counter % 7 == 0) {
double center = (min + max) / 2.0;
value = center + (value - center) * 0.4;
}
return value;
}
private static double stepped(double min, double max) {
double range = max - min;
int steps = 5 + baseRandom.nextInt(6); // 5-10 ступеней
// Определение текущей ступени
int currentStep = (int) (steps * baseRandom.nextDouble());
// Периодическое изменение ступеней
if (counter % 4 == 0) {
currentStep = (currentStep + 1 + baseRandom.nextInt(2)) % steps;
}
// Генерация значения в пределах ступени
double stepSize = range / steps;
double stepMin = min + currentStep * stepSize;
double stepMax = stepMin + stepSize;
return stepMin + baseRandom.nextDouble() * (stepMax - stepMin);
}
private static double chaoticSmooth(double min, double max) {
if (Double.isNaN(lastValue)) {
return baseRandom.nextDouble() * (max - min) + min;
}
// Хаотичное но плавное изменение
double range = max - min;
double chaosFactor = 0.2 + baseRandom.nextDouble() * 0.5;
double direction = baseRandom.nextBoolean() ? 1 : -1;
// Нелинейное изменение
double delta = range * chaosFactor * direction * Math.sin(counter * 0.5);
double newValue = lastValue + delta;
// Коррекция при выходе за границы
if (newValue < min || newValue > max) {
double anchor = min + range * (0.1 + 0.8 * baseRandom.nextDouble());
return anchor;
}
return newValue;
}
private static double humanTremor(double min, double max) {
double baseValue = Double.isNaN(lastValue)
? (min + max) / 2.0
: lastValue;
// Псевдо-периодический тремор
double tremorIntensity = 0.02 + Math.sin(counter * 0.3) * 0.01;
double tremor = Math.sin(counter * 12.7) * tremorIntensity * (max - min);
// Случайные микро-скачки
if(counter % 15 == 0) {
tremor += baseRandom.nextGaussian() * 0.04 * (max - min);
}
return constrain(baseValue + tremor, min, max);
}
private static double saccadicMovement(double min, double max) {
if(Double.isNaN(lastValue)) {
return min + baseRandom.nextDouble() * (max - min);
}
// Длительность фиксации (200-500мс)
int fixationDuration = 10 + baseRandom.nextInt(15);
if(counter % fixationDuration == 0) {
// Саккадический скачок
double jumpSize = (max - min) * (0.1 + baseRandom.nextDouble() * 0.15);
int direction = baseRandom.nextBoolean() ? 1 : -1;
return constrain(lastValue + jumpSize * direction, min, max);
}
// Микродвижения во время фиксации
return lastValue + baseRandom.nextGaussian() * 0.015 * (max - min);
}
private static double microCorrections(double min, double max) {
double target = Double.isNaN(lastValue)
? min + (max - min) * (0.3 + baseRandom.nextDouble() * 0.4)
: lastValue;
// Периодические коррекции
if(counter % (8 + baseRandom.nextInt(5)) == 0) {
double overshoot = (max - min) * 0.08 * (baseRandom.nextGaussian() + 0.5);
target += baseRandom.nextBoolean() ? overshoot : -overshoot;
}
// Постоянные микрокоррекции
double correction = (target - lastValue) * 0.15 + baseRandom.nextGaussian() * 0.01;
return constrain(lastValue + correction, min, max);
}
private static double inertiaSmooth(double min, double max) {
if(Double.isNaN(lastValue)) {
return min + baseRandom.nextDouble() * (max - min);
}
// Инерция и плавное замедление
double velocity = Double.isNaN(lastVelocity)
? (max - min) * 0.005 * (baseRandom.nextGaussian() + 0.3)
: lastVelocity * 0.85;
// Случайное изменение направления
if(baseRandom.nextDouble() < 0.07) {
velocity *= -0.5 + baseRandom.nextDouble();
}
double newValue = lastValue + velocity;
lastVelocity = velocity;
// Коррекция у границ
if(newValue < min || newValue > max) {
lastVelocity *= -0.7;
return constrain(lastValue + lastVelocity, min, max);
}
return newValue;
}
private static double interia2(double min, double max){
if(Double.isNaN(lastValue)) {
// Инициализация
lastVelocity = (baseRandom.nextGaussian() * 0.5 + 0.3) * (max - min) * 0.01;
return min + baseRandom.nextDouble() * (max - min);
}
// Инерция и плавное замедление
lastVelocity *= 0.82;
// Случайное ускорение
if(baseRandom.nextDouble() < 0.12) {
lastVelocity += (baseRandom.nextGaussian() * 0.7) * (max - min) * 0.005;
}
double newValue = lastValue + lastVelocity;
// Коррекция у границ
if(newValue < min || newValue > max) {
lastVelocity *= -0.65; // Отскок с потерей энергии
return constrain(lastValue + lastVelocity, min, max);
}
return newValue;
}
private static double fatigueDrift(double min, double max) {
if(Double.isNaN(lastValue)) {
return min + (max - min) * 0.5;
}
// Накопленная усталость
double fatigueFactor = Math.min(1.0, counter / 300.0);
// Дрейф в зависимости от усталости
double drift = (baseRandom.nextDouble() - 0.4) * fatigueFactor * 0.08 * (max - min);
// Периодические осознанные коррекции
if(counter % (30 - (int)(fatigueFactor * 15)) == 0) {
double correction = ((min + max)/2 - lastValue) * (0.3 + baseRandom.nextDouble() * 0.4);
drift += correction;
}
return constrain(lastValue + drift, min, max);
}
private static double ADVfatigueDrift(double min, double max) {
if(Double.isNaN(lastValue)) {
fatigueCounter = 0;
return min + (max - min) * 0.5;
}
fatigueCounter++;
// Накопленная усталость (0-100%)
double fatigueFactor = Math.min(1.0, fatigueCounter / 250.0);
// Дрейф в зависимости от усталости
double drift = (baseRandom.nextDouble() - 0.42) * fatigueFactor * 0.06 * (max - min);
// Периодические коррекции (реже при усталости)
int correctionInterval = 35 - (int)(fatigueFactor * 20);
if(correctionInterval < 8) correctionInterval = 8;
if(fatigueCounter % correctionInterval == 0) {
double correction = ((min + max)/2 - lastValue) * (0.25 + baseRandom.nextDouble() * 0.35);
drift += correction;
// Сброс усталости после коррекции
fatigueCounter = (int)(fatigueCounter * 0.6);
}
return constrain(lastValue + drift, min, max);
}
// Сброс состояния генератора
public static void resetState() {
lastValue = Double.NaN;
counter = 0;
}
}