Skip to content

Instantly share code, notes, and snippets.

@alcatrazEscapee
Created November 17, 2021 20:36
Show Gist options
  • Save alcatrazEscapee/d0b2accaf3ed70a6eb8ad12b9e762214 to your computer and use it in GitHub Desktop.
Save alcatrazEscapee/d0b2accaf3ed70a6eb8ad12b9e762214 to your computer and use it in GitHub Desktop.
Prototype, untested age/familiarity fast forwarding mechanic.
package net.dries007.tfc.common.entities;
import net.dries007.tfc.util.Helpers;
import net.dries007.tfc.util.calendar.Calendars;
import net.dries007.tfc.util.calendar.ICalendar;
public class AgeTracker
{
public static final float AGE_RATE = 0.5f / ICalendar.TICKS_IN_DAY;
public static final float FAMILIARITY_DECAY_RATE = 0.1f / ICalendar.TICKS_IN_DAY; // Familiarity decay / tick
public static final float FAMILIARITY_DECAY_CAP = 0.3f; // Familiarity required before it does not decay
public static final float FAMILIARITY_AGE_CAP = 0.2f; // Familiarity required for full speed aging
private float age;
private float familiarity;
private long lastTick;
/**
* @return Age, in [0, 1]
*/
public float getAge()
{
update();
return age;
}
public float getFamiliarity()
{
update();
return familiarity;
}
public void addFamiliarity(float amount)
{
update();
familiarity += amount;
if (familiarity > 1)
{
familiarity = 1;
}
}
private void update()
{
final long currentTick = Calendars.SERVER.getTicks();
final long tickDelta = currentTick - lastTick;
if (familiarity < FAMILIARITY_DECAY_CAP)
{
float deltaAge;
final float deltaFamiliarity = tickDelta * FAMILIARITY_DECAY_RATE;
if (deltaFamiliarity < familiarity)
{
// Result familiarity > 0, we can use mean value theorem. Check for the cap value
familiarity -= deltaFamiliarity;
if (familiarity > FAMILIARITY_AGE_CAP)
{
// cap < t1 < t2, so max age rate
deltaAge = tickDelta * AGE_RATE;
}
else if (familiarity + deltaFamiliarity > FAMILIARITY_AGE_CAP)
{
// t1 < cap < t2
final float t = Helpers.inverseLerp(FAMILIARITY_AGE_CAP, familiarity + deltaFamiliarity, familiarity);
final float r = t + (1 - t) * Helpers.inverseLerp(familiarity + deltaFamiliarity * 0.5f, 0, FAMILIARITY_AGE_CAP);
deltaAge = tickDelta * r;
}
else
{
// t1 < t2 < cap
final float r = Helpers.inverseLerp(familiarity + deltaFamiliarity * 0.5f, 0, FAMILIARITY_AGE_CAP);
deltaAge = tickDelta * r;
}
}
else
{
// Familiarity decays to zero. Calculated reduced (aging) tick delta.
final float reducedTickDelta = tickDelta * Helpers.inverseLerp(0, familiarity, familiarity - deltaFamiliarity);
if (familiarity > FAMILIARITY_AGE_CAP)
{
// 0 < cap < t
final float t = Helpers.inverseLerp(FAMILIARITY_AGE_CAP, familiarity, 0);
final float r = t + (1 - t) * familiarity * 0.5f;
deltaAge = reducedTickDelta * r;
}
else
{
// 0 < t < cap
final float r = Helpers.inverseLerp(familiarity * 0.5f, 0, FAMILIARITY_AGE_CAP);
deltaAge = reducedTickDelta * r;
}
familiarity = 0;
}
age += deltaAge;
}
lastTick = currentTick;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment