mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 02:37:27 +00:00
Made animation threading compatible on the client & server side
This commit is contained in:
1 parent
cf4e5f22b1
commit
16c3395d8c
6 files changed
+176
-48
No files matched your search
@@ -1,7 +1,11 @@
|
||||
package noppes.npcs;
|
||||
|
||||
import cpw.mods.fml.common.network.IGuiHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
@@ -14,19 +18,80 @@ import noppes.npcs.api.IWorld;
|
||||
import noppes.npcs.blocks.tiles.TileNpcContainer;
|
||||
import noppes.npcs.constants.EnumGuiType;
|
||||
import noppes.npcs.containers.*;
|
||||
import noppes.npcs.controllers.data.Animation;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
import noppes.npcs.util.MillisTimer;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class CommonProxy implements IGuiHandler {
|
||||
|
||||
public boolean newVersionAvailable = false;
|
||||
public int revision = 1;
|
||||
public static HashSet<Animation> clientPlayingAnimations = new HashSet<>();
|
||||
public static HashSet<Animation> serverPlayingAnimations = new HashSet<>();
|
||||
protected MillisTimer animationTimer = new MillisTimer(1000);
|
||||
protected long totalTicks;
|
||||
|
||||
public void load() {
|
||||
this.createAnimationThread();
|
||||
|
||||
CustomNpcs.Channel.register(new PacketHandlerServer());
|
||||
CustomNpcs.ChannelPlayer.register(new PacketHandlerPlayer());
|
||||
}
|
||||
|
||||
protected void createAnimationThread() {
|
||||
Thread thread = (new Thread("Animation Thread") { public void run() {
|
||||
while (true) {
|
||||
if (!CustomNpcs.proxy.hasClient() || !Minecraft.getMinecraft().isGamePaused()) {
|
||||
animationTimer.updateTimer();
|
||||
}
|
||||
|
||||
HashSet<Animation> playingAnimations = CustomNpcs.proxy.hasClient() ? clientPlayingAnimations : serverPlayingAnimations;
|
||||
for (int i = 0; i < animationTimer.elapsedTicks; ++i) {
|
||||
for (Animation animation : playingAnimations) {
|
||||
if (animation.parent.isActive() && totalTicks % animation.currentFrame().tickDuration() == 0) {
|
||||
animation.increaseTime();
|
||||
}
|
||||
}
|
||||
totalTicks++;
|
||||
}
|
||||
totalTicks %= 60 * 60 * 1000;
|
||||
clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation);
|
||||
serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation);
|
||||
}
|
||||
}});
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private boolean removeAnimation(Animation animation) {
|
||||
if (animation.parent == null || animation.parent.animation != animation) return true;
|
||||
|
||||
Entity entity = null;
|
||||
if (animation.parent.parent instanceof DataDisplay) {
|
||||
entity = ((DataDisplay)animation.parent.parent).npc;
|
||||
} else {
|
||||
if (animation.parent.parent instanceof PlayerData) {
|
||||
entity = ((PlayerData) animation.parent.parent).player;
|
||||
} else if (animation.parent.parent instanceof EntityPlayer) {
|
||||
entity = (EntityPlayer) animation.parent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity == null) return true;
|
||||
|
||||
if (CustomNpcs.proxy.hasClient()) {
|
||||
return clientRemoveAnimation(entity);
|
||||
} else {
|
||||
return entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private boolean clientRemoveAnimation(Entity entity) {
|
||||
return Minecraft.getMinecraft().currentScreen == null
|
||||
&& !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity);
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData(EntityPlayer player) {
|
||||
return null;
|
||||
}
|
||||
@@ -166,4 +231,4 @@ public class CommonProxy implements IGuiHandler {
|
||||
public boolean isGUIOpen(){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package noppes.npcs.client;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import noppes.npcs.CommonProxy;
|
||||
import noppes.npcs.client.gui.OverlayQuestTracking;
|
||||
import noppes.npcs.client.gui.customoverlay.OverlayCustom;
|
||||
import noppes.npcs.client.renderer.ImageData;
|
||||
@@ -21,7 +22,6 @@ public class ClientCacheHandler {
|
||||
public static HashMap<UUID, HashMap<Integer, SkinOverlay>> skinOverlays = new HashMap<>();
|
||||
|
||||
public static HashMap<UUID, AnimationData> playerAnimations = new HashMap<>();
|
||||
public static HashSet<Animation> playingAnimations = new HashSet<>();
|
||||
|
||||
public static Party party;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ClientCacheHandler {
|
||||
ClientCacheHandler.skinOverlays.clear();
|
||||
ClientCacheHandler.playerAnimations.clear();
|
||||
ClientCacheHandler.playerData.animationData.clearCache();
|
||||
ClientCacheHandler.playingAnimations.clear();
|
||||
CommonProxy.clientPlayingAnimations.clear();
|
||||
}
|
||||
|
||||
public static void clearSkinCache() {
|
||||
|
||||
@@ -23,7 +23,6 @@ import net.minecraft.stats.Achievement;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ReportedException;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Timer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -60,7 +59,6 @@ import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.config.StringCache;
|
||||
import noppes.npcs.constants.EnumGuiType;
|
||||
import noppes.npcs.containers.*;
|
||||
import noppes.npcs.controllers.data.Animation;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.entity.*;
|
||||
import noppes.npcs.entity.data.ModelData;
|
||||
@@ -82,33 +80,8 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
public static FontContainer Font;
|
||||
|
||||
private static Timer animationTimer = new Timer(1000);
|
||||
private static long totalTicks;
|
||||
|
||||
public void load() {
|
||||
Thread thread = (new Thread("Animation Thread") { public void run() {
|
||||
while (true) {
|
||||
if (!Minecraft.getMinecraft().isGamePaused()) {
|
||||
animationTimer.updateTimer();
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < animationTimer.elapsedTicks; ++i) {
|
||||
for (Animation animation : ClientCacheHandler.playingAnimations) {
|
||||
if (animation.parent.isActive() && totalTicks % animation.currentFrame().tickDuration() == 0) {
|
||||
animation.increaseTime();
|
||||
}
|
||||
}
|
||||
totalTicks++;
|
||||
}
|
||||
totalTicks %= 60 * 60 * 1000;
|
||||
ClientCacheHandler.playingAnimations.removeIf(animation ->
|
||||
animation.parent.animation != animation || !animation.parent.isActive());
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}});
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
this.createAnimationThread();
|
||||
|
||||
Font = new FontContainer(ConfigClient.FontType, ConfigClient.FontSize);
|
||||
createFolders();
|
||||
|
||||
@@ -220,7 +220,6 @@ public class Animation implements IAnimation {
|
||||
return compound;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void increaseTime() {
|
||||
if (paused)
|
||||
return;
|
||||
|
||||
@@ -9,6 +9,8 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import noppes.npcs.CommonProxy;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.DataDisplay;
|
||||
import noppes.npcs.Server;
|
||||
import noppes.npcs.api.handler.data.IAnimation;
|
||||
@@ -56,6 +58,10 @@ public class AnimationData implements IAnimationData {
|
||||
EntityLivingBase sendingEntity = parent instanceof PlayerData ? ((PlayerData) parent).player : parent instanceof DataDisplay ? ((DataDisplay) parent).npc : null;
|
||||
float range = parent instanceof PlayerData ? 160 : 60;
|
||||
if (sendingEntity != null) {
|
||||
if (!CustomNpcs.proxy.hasClient()) {
|
||||
CommonProxy.serverPlayingAnimations.add(this.animation);
|
||||
}
|
||||
|
||||
List<EntityPlayer> entities = sendingEntity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(
|
||||
sendingEntity.posX - range, sendingEntity.posY - range, sendingEntity.posZ - range,
|
||||
sendingEntity.posX + range, sendingEntity.posY + range, sendingEntity.posZ + range));
|
||||
@@ -153,18 +159,20 @@ public class AnimationData implements IAnimationData {
|
||||
}
|
||||
|
||||
public void setAnimation(IAnimation animation) {
|
||||
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
|
||||
this.animation = (Animation) animation;
|
||||
} else {
|
||||
this.clientSetAnimation(animation);
|
||||
Animation newAnim = null;
|
||||
if (animation != null) {
|
||||
newAnim = new Animation();
|
||||
newAnim.readFromNBT(((Animation) animation).writeToNBT());
|
||||
newAnim.parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void clientSetAnimation(IAnimation animation) {
|
||||
Animation newAnim = new Animation();
|
||||
newAnim.readFromNBT(((Animation) animation).writeToNBT());
|
||||
if (this.isActive() && !newAnim.frames.isEmpty()) {
|
||||
if (CustomNpcs.proxy.hasClient() && newAnim != null) {
|
||||
CommonProxy.clientPlayingAnimations.remove(this.animation);
|
||||
CommonProxy.clientPlayingAnimations.add(newAnim);
|
||||
}
|
||||
this.animation = newAnim;
|
||||
|
||||
if (this.isActive() && newAnim != null && !newAnim.frames.isEmpty()) {
|
||||
Frame frame = (Frame) this.animation.currentFrame();
|
||||
if (frame != null) {
|
||||
Frame firstFrame = newAnim.frames.get(0);
|
||||
@@ -180,9 +188,6 @@ public class AnimationData implements IAnimationData {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.animation = newAnim;
|
||||
newAnim.parent = this;
|
||||
ClientCacheHandler.playingAnimations.add(newAnim);
|
||||
}
|
||||
|
||||
public IAnimation getAnimation() {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package noppes.npcs.util;
|
||||
|
||||
import org.lwjgl.Sys;
|
||||
|
||||
public class MillisTimer {
|
||||
float ticksPerSecond;
|
||||
private double lastHRTime;
|
||||
public int elapsedTicks;
|
||||
public float renderPartialTicks;
|
||||
public float timerSpeed = 1.0F;
|
||||
public float elapsedPartialTicks;
|
||||
private long lastSyncSysClock;
|
||||
private long lastSyncHRClock;
|
||||
private long field_74285_i;
|
||||
private double timeSyncAdjustment = 1.0D;
|
||||
|
||||
public MillisTimer(float p_i1018_1_)
|
||||
{
|
||||
this.ticksPerSecond = p_i1018_1_;
|
||||
this.lastSyncSysClock = this.getLastSyncSysClock();
|
||||
this.lastSyncHRClock = System.nanoTime() / 1000000L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all fields of the Timer using the current time
|
||||
*/
|
||||
public void updateTimer()
|
||||
{
|
||||
long i = this.getLastSyncSysClock();
|
||||
long j = i - this.lastSyncSysClock;
|
||||
long k = System.nanoTime() / 1000000L;
|
||||
double d0 = (double)k / 1000.0D;
|
||||
|
||||
if (j <= 1000L && j >= 0L)
|
||||
{
|
||||
this.field_74285_i += j;
|
||||
|
||||
if (this.field_74285_i > 1000L)
|
||||
{
|
||||
long l = k - this.lastSyncHRClock;
|
||||
double d1 = (double)this.field_74285_i / (double)l;
|
||||
this.timeSyncAdjustment += (d1 - this.timeSyncAdjustment) * 0.20000000298023224D;
|
||||
this.lastSyncHRClock = k;
|
||||
this.field_74285_i = 0L;
|
||||
}
|
||||
|
||||
if (this.field_74285_i < 0L)
|
||||
{
|
||||
this.lastSyncHRClock = k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.lastHRTime = d0;
|
||||
}
|
||||
|
||||
this.lastSyncSysClock = i;
|
||||
double d2 = (d0 - this.lastHRTime) * this.timeSyncAdjustment;
|
||||
this.lastHRTime = d0;
|
||||
|
||||
if (d2 < 0.0D)
|
||||
{
|
||||
d2 = 0.0D;
|
||||
}
|
||||
|
||||
if (d2 > 1.0D)
|
||||
{
|
||||
d2 = 1.0D;
|
||||
}
|
||||
|
||||
this.elapsedPartialTicks = (float)((double)this.elapsedPartialTicks + d2 * (double)this.timerSpeed * (double)this.ticksPerSecond);
|
||||
this.elapsedTicks = (int)this.elapsedPartialTicks;
|
||||
this.elapsedPartialTicks -= (float)this.elapsedTicks;
|
||||
|
||||
if (this.elapsedTicks > 10)
|
||||
{
|
||||
this.elapsedTicks = 10;
|
||||
}
|
||||
|
||||
this.renderPartialTicks = this.elapsedPartialTicks;
|
||||
}
|
||||
|
||||
private long getLastSyncSysClock() {
|
||||
return Sys.getTime() * 1000L / Sys.getTimerResolution();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user