fix all of the bullshit!!

Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
This commit is contained in:
Octol1ttle 2024-07-15 13:18:14 +05:00
parent 5fee6404b0
commit ac41344a3c
Signed by: Octol1ttle
GPG key ID: B77C34313AEE1FFF
14 changed files with 214 additions and 243 deletions

18
LICENSE
View file

@ -1,21 +1,11 @@
MIT License
All Rights Reserved
Copyright (c) 2022 CleanroomMC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Copyright (c) 2024 Octol1ttle
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,17 +1,113 @@
package ru.octol1ttle.knockdowns.client;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import ru.octol1ttle.knockdowns.client.communication.CalloutManager;
import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
import ru.octol1ttle.knockdowns.client.event.KnockdownsKeyListener;
import ru.octol1ttle.knockdowns.client.util.DirectionalCallSound;
import ru.octol1ttle.knockdowns.common.IClientProxy;
import ru.octol1ttle.knockdowns.common.KnockdownsMod;
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerKnockedDownS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
import ru.octol1ttle.knockdowns.common.registry.KnockdownsSoundEvents;
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
@SideOnly(Side.CLIENT)
public class ClientProxy implements IClientProxy {
private static final Minecraft client = Minecraft.getMinecraft();
@Override
public void onFMLInit(FMLInitializationEvent event) {
KnockdownsMod.LOGGER.info("Registering key bindings");
KnockdownsKeyListener.registerKeyBindings();
}
@Override
public <T> T handleMessage(IMessage message) {
if (message instanceof PlayerCalloutS2CPacket) {
PlayerCalloutS2CPacket packet = (PlayerCalloutS2CPacket) message;
client.addScheduledTask(() -> {
if (CalloutManager.addOrUpdateCallout(packet)) {
CalloutManager.playCalloutSound(packet);
}
});
} else if (message instanceof PlayerKnockedDownS2CPacket) {
PlayerKnockedDownS2CPacket packet = (PlayerKnockedDownS2CPacket) message;
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(true);
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
data.getRevivers().clear();
}
if (client.player.dimension == packet.dimensionId) {
client.getSoundHandler().playSound(new DirectionalCallSound(KnockdownsSoundEvents.KNOCKED_DOWN, entity, packet.position));
KnockedNotificationManager.addKnockedNotification(packet.playerId, packet.position);
}
});
} else if (message instanceof SynchronizePlayerDataS2CPacket.KnockedDown) {
SynchronizePlayerDataS2CPacket.KnockedDown packet = (SynchronizePlayerDataS2CPacket.KnockedDown) message;
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(packet.knockedDown);
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
data.getRevivers().clear();
}
});
} else if (message instanceof SynchronizePlayerDataS2CPacket.ReviveTimeLeft) {
SynchronizePlayerDataS2CPacket.ReviveTimeLeft packet = (SynchronizePlayerDataS2CPacket.ReviveTimeLeft) message;
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setReviveTimeLeft(packet.reviveTimeLeft);
}
});
} else if (message instanceof SynchronizePlayerDataS2CPacket.Full) {
SynchronizePlayerDataS2CPacket.Full packet = (SynchronizePlayerDataS2CPacket.Full) message;
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(packet.knockedDown);
data.setReviveTimeLeft(packet.reviveTimeLeft);
}
});
} else if (message instanceof SynchronizeReviversS2CPacket.Add) {
SynchronizeReviversS2CPacket.Add packet = (SynchronizeReviversS2CPacket.Add) message;
client.addScheduledTask(() -> {
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(packet.knockedId);
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(packet.reviverId);
if (knocked != null && reviver != null) {
IKnockdownsPlayerData.get(knocked).getRevivers().add(reviver);
}
});
} else if (message instanceof SynchronizeReviversS2CPacket.Remove) {
SynchronizeReviversS2CPacket.Remove packet = (SynchronizeReviversS2CPacket.Remove) message;
client.addScheduledTask(() -> {
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(packet.knockedId);
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(packet.reviverId);
if (knocked != null && reviver != null) {
IKnockdownsPlayerData.get(knocked).getRevivers().remove(reviver);
}
});
} else {
throw new IllegalStateException("Unknown packet received on the client: " + message.getClass().getName());
}
return null;
}
}

View file

@ -17,7 +17,7 @@ import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
import ru.octol1ttle.knockdowns.client.gui.CommunicationGui;
import ru.octol1ttle.knockdowns.client.gui.KnockedNotificationGui;
import ru.octol1ttle.knockdowns.client.gui.ReviveGui;
import ru.octol1ttle.knockdowns.common.ReviverTracker;
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
@ -45,7 +45,7 @@ public class KnockdownsClientEventListener {
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
List<EntityPlayer> revivers = ReviverTracker.getRevivers(event.player);
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(event.player).getRevivers();
if (revivers.contains(client.player) && !event.player.equals(client.pointedEntity)) {
KnockdownsNetwork.sendToServer(new CancelReviveC2SPacket());
revivers.remove(client.player);
@ -54,8 +54,8 @@ public class KnockdownsClientEventListener {
@SubscribeEvent
public static void onRenderWorldLast(RenderWorldLastEvent event) {
communicationGui.renderCallouts(event.getPartialTicks());
notificationGui.renderNotifications(event.getPartialTicks());
communicationGui.renderCallouts(event.getPartialTicks());
}
@SubscribeEvent

View file

@ -6,7 +6,6 @@ import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextFormatting;
import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
import ru.octol1ttle.knockdowns.common.ReviverTracker;
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
public class ReviveGui extends KnockdownsBaseGui {
@ -15,7 +14,7 @@ public class ReviveGui extends KnockdownsBaseGui {
@Override
public void render(float partialTicks, ScaledResolution resolution) {
EntityPlayer reviving =
client.pointedEntity instanceof EntityPlayer && ReviverTracker.getRevivers((EntityPlayer) client.pointedEntity).contains(client.player)
client.pointedEntity instanceof EntityPlayer && IKnockdownsPlayerData.get((EntityPlayer) client.pointedEntity).getRevivers().contains(client.player)
? (EntityPlayer) client.pointedEntity
: client.player;
if (IKnockdownsPlayerData.get(reviving).getReviveTimeLeft() == KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT) {
@ -28,7 +27,8 @@ public class ReviveGui extends KnockdownsBaseGui {
String timerText = String.format("%.1f", data.getReviveTimeLeft() / 20.0f);
float timerX = (resolution.getScaledWidth() - font.getStringWidth(timerText)) * 0.5f;
int reviverCount = ReviverTracker.getRevivers(reviving).size();
data.getRevivers().removeIf(reviver -> reviver.isDead || !reviver.isEntityAlive() || IKnockdownsPlayerData.get(reviver).isKnockedDown());
int reviverCount = data.getRevivers().size();
TextFormatting color;
if (reviverCount == 0) {
color = TextFormatting.RED;
@ -41,7 +41,7 @@ public class ReviveGui extends KnockdownsBaseGui {
String reviverCountText = "x" + reviverCount;
float reviveCountX = (resolution.getScaledWidth() - font.getStringWidth(reviverCountText)) * 0.5f;
font.drawStringWithShadow(color + timerText, timerX, resolution.getScaledHeight() * 0.5f + 5, 553648127);
font.drawStringWithShadow(color + reviverCountText, reviveCountX, resolution.getScaledHeight() * 0.5f + 14, 553648127);
font.drawStringWithShadow(color + timerText, timerX, resolution.getScaledHeight() * 0.5f + 5, 0xFFFFFF);
font.drawStringWithShadow(color + reviverCountText, reviveCountX, resolution.getScaledHeight() * 0.5f + 14, 0xFFFFFF);
}
}

View file

@ -1,145 +0,0 @@
package ru.octol1ttle.knockdowns.client.network;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import ru.octol1ttle.knockdowns.client.communication.CalloutManager;
import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
import ru.octol1ttle.knockdowns.client.util.DirectionalCallSound;
import ru.octol1ttle.knockdowns.common.ReviverTracker;
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerKnockedDownS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
import ru.octol1ttle.knockdowns.common.registry.KnockdownsSoundEvents;
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
public class KnockdownsClientPacketHandler {
public static class Callout implements IMessageHandler<PlayerCalloutS2CPacket, IMessage> {
private static final Minecraft client = Minecraft.getMinecraft();
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(PlayerCalloutS2CPacket message, MessageContext ctx) {
client.addScheduledTask(() -> {
if (CalloutManager.addOrUpdateCallout(message)) {
CalloutManager.playCalloutSound(message);
}
});
return null;
}
}
public static class PlayerKnockedDown implements IMessageHandler<PlayerKnockedDownS2CPacket, IMessage> {
private static final Minecraft client = Minecraft.getMinecraft();
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(PlayerKnockedDownS2CPacket message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(message.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(true);
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
}
if (client.player.dimension == message.dimensionId) {
client.getSoundHandler().playSound(new DirectionalCallSound(KnockdownsSoundEvents.KNOCKED_DOWN, entity, message.position));
KnockedNotificationManager.addKnockedNotification(message.playerId, message.position);
}
});
return null;
}
}
public static class SynchronizePlayerData {
private static final Minecraft client = Minecraft.getMinecraft();
public static class KnockedDown implements IMessageHandler<SynchronizePlayerDataS2CPacket.KnockedDown, IMessage> {
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(SynchronizePlayerDataS2CPacket.KnockedDown message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(message.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(message.knockedDown);
}
});
return null;
}
}
public static class ReviveTimeLeft implements IMessageHandler<SynchronizePlayerDataS2CPacket.ReviveTimeLeft, IMessage> {
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(SynchronizePlayerDataS2CPacket.ReviveTimeLeft message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(message.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setReviveTimeLeft(message.reviveTimeLeft);
}
});
return null;
}
}
public static class Full implements IMessageHandler<SynchronizePlayerDataS2CPacket.Full, IMessage> {
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(SynchronizePlayerDataS2CPacket.Full message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(message.playerId);
if (entity != null) {
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
data.setKnockedDown(message.knockedDown);
data.setReviveTimeLeft(message.reviveTimeLeft);
}
});
return null;
}
}
}
public static class SynchronizeRevivers {
private static final Minecraft client = Minecraft.getMinecraft();
public static class Add implements IMessageHandler<SynchronizeReviversS2CPacket.Add, IMessage> {
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(SynchronizeReviversS2CPacket.Add message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(message.knockedId);
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(message.reviverId);
if (knocked != null && reviver != null) {
ReviverTracker.startReviving(knocked, reviver);
}
});
return null;
}
}
public static class Remove implements IMessageHandler<SynchronizeReviversS2CPacket.Remove, IMessage> {
@SideOnly(Side.CLIENT)
@Override
public IMessage onMessage(SynchronizeReviversS2CPacket.Remove message, MessageContext ctx) {
client.addScheduledTask(() -> {
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(message.knockedId);
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(message.reviverId);
if (knocked != null && reviver != null) {
ReviverTracker.stopReviving(knocked, reviver);
}
});
return null;
}
}
}
}

View file

@ -1,13 +1,21 @@
package ru.octol1ttle.knockdowns.common;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public interface IClientProxy {
void onFMLInit(FMLInitializationEvent event);
<T> T handleMessage(IMessage message);
class Dummy implements IClientProxy {
@Override
public void onFMLInit(FMLInitializationEvent event) {
}
@Override
public <T> T handleMessage(IMessage message) {
return null;
}
}
}

View file

@ -1,7 +1,6 @@
package ru.octol1ttle.knockdowns.common;
import java.util.List;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
@ -70,32 +69,33 @@ public class KnockdownsCommonEventListener {
if (event.phase == TickEvent.Phase.START || server == null) {
return;
}
EntityPlayerMP player = (EntityPlayerMP) event.player;
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(player);
EntityPlayerMP knocked = (EntityPlayerMP) event.player;
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(knocked);
if (!data.isKnockedDown()) {
return;
}
if (allPlayersKnocked(server, player)) {
player.attackEntityFrom(DamageSource.GENERIC, player.getMaxHealth());
if (allPlayersKnocked(server, knocked)) {
knocked.attackEntityFrom(DamageSource.GENERIC, knocked.getMaxHealth());
return;
}
List<EntityPlayer> revivers = ReviverTracker.getRevivers(player);
List<EntityPlayer> revivers = data.getRevivers();
revivers.removeIf(reviver -> reviver.isDead || !reviver.isEntityAlive() || IKnockdownsPlayerData.get(reviver).isKnockedDown());
if (!revivers.isEmpty()) {
data.setReviveTimeLeft(data.getReviveTimeLeft() - revivers.size());
KnockdownsNetwork.sendToMultiple(
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(player.getEntityId(), data.getReviveTimeLeft()),
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(knocked.getEntityId(), data.getReviveTimeLeft()),
revivers,
player
knocked
);
if (data.getReviveTimeLeft() <= 0) {
resetKnockedState(player, data);
resetKnockedState(knocked, data);
player.setEntityInvulnerable(false);
player.setHealth(player.getMaxHealth() * 0.3f);
player.setAbsorptionAmount(0.0f);
knocked.setEntityInvulnerable(false);
knocked.setHealth(knocked.getMaxHealth() * 0.3f);
knocked.setAbsorptionAmount(0.0f);
}
return;
}
@ -104,8 +104,8 @@ public class KnockdownsCommonEventListener {
data.setReviveTimeLeft(Math.min(INITIAL_REVIVE_TIME_LEFT, oldReviveTimeLeft + 1));
if (data.getReviveTimeLeft() != oldReviveTimeLeft) {
KnockdownsNetwork.sendToPlayer(
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(player.getEntityId(), data.getReviveTimeLeft()),
player
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(knocked.getEntityId(), data.getReviveTimeLeft()),
knocked
);
}
@ -113,8 +113,8 @@ public class KnockdownsCommonEventListener {
int period = MathHelper.floor(KNOCKED_HURT_PERIOD * 20);
if (data.getTicksKnocked() >= KNOCKED_INVULNERABILITY_TICKS && data.getTicksKnocked() % period == 0) {
player.setEntityInvulnerable(false);
player.attackEntityFrom(DamageSource.GENERIC, player.getMaxHealth() / (KNOCKED_TENACITY / KNOCKED_HURT_PERIOD));
knocked.setEntityInvulnerable(false);
knocked.attackEntityFrom(DamageSource.GENERIC, knocked.getMaxHealth() / (KNOCKED_TENACITY / KNOCKED_HURT_PERIOD));
}
}
@ -131,7 +131,7 @@ public class KnockdownsCommonEventListener {
}
if (data.isKnockedDown() || allPlayersKnocked(player.getServer(), player)) {
ReviverTracker.clearRevivers(player);
data.getRevivers().clear();
return;
}
@ -159,10 +159,9 @@ public class KnockdownsCommonEventListener {
TextComponentTranslation deathMessage = (TextComponentTranslation) player.getCombatTracker().getDeathMessage();
String knockdownKey = deathMessage.getKey().replace("death.", "knockdown.");
TextComponentTranslation knockdownTranslation = new TextComponentTranslation(knockdownKey, deathMessage.getFormatArgs());
player.getServer().getPlayerList().sendMessage(
I18n.hasKey(knockdownKey)
? new TextComponentTranslation(knockdownKey, deathMessage.getFormatArgs())
: deathMessage,
!knockdownTranslation.getUnformattedComponentText().equals(knockdownKey) ? knockdownTranslation : deathMessage,
true
);
@ -212,15 +211,23 @@ public class KnockdownsCommonEventListener {
}
public static void onPlayerInteraction(PlayerInteractEvent.EntityInteract event) {
if (event.getEntityLiving() instanceof EntityPlayerMP) {
EntityPlayerMP knocked = (EntityPlayerMP) event.getEntityLiving();
if (IKnockdownsPlayerData.get(knocked).isKnockedDown()) {
if (event.getTarget() instanceof EntityPlayerMP) {
EntityPlayerMP knocked = (EntityPlayerMP) event.getTarget();
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(knocked);
if (data.isKnockedDown() && !data.getRevivers().contains(event.getEntityPlayer())) {
for (EntityPlayer reviver : data.getRevivers()) {
KnockdownsNetwork.sendToPlayer(
new SynchronizeReviversS2CPacket.Add(event.getTarget().getEntityId(), reviver.getEntityId()),
(EntityPlayerMP) event.getEntityPlayer()
);
}
data.getRevivers().add(event.getEntityPlayer());
KnockdownsNetwork.sendToMultiple(
new SynchronizeReviversS2CPacket.Add(event.getEntityLiving().getEntityId(), event.getEntityPlayer().getEntityId()),
ReviverTracker.getRevivers(knocked),
new SynchronizeReviversS2CPacket.Add(event.getTarget().getEntityId(), event.getEntityPlayer().getEntityId()),
data.getRevivers(),
knocked
);
ReviverTracker.startReviving(knocked, event.getEntityPlayer());
}
}
}
@ -236,6 +243,17 @@ public class KnockdownsCommonEventListener {
@SubscribeEvent
public static void onPlayerLeave(PlayerLoggedOutEvent event) {
ReviverTracker.clearRevivers(event.player);
for (EntityPlayer knocked : event.player.world.playerEntities) {
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(knocked).getRevivers();
if (revivers.contains(event.player)) {
revivers.remove(event.player);
KnockdownsNetwork.sendToMultiple(
new SynchronizeReviversS2CPacket.Remove(knocked.getEntityId(), event.player.getEntityId()),
revivers,
(EntityPlayerMP) knocked
);
break;
}
}
}
}

View file

@ -38,6 +38,6 @@ public class KnockdownsUtils {
player
);
ReviverTracker.clearRevivers(player);
data.getRevivers().clear();
}
}

View file

@ -1,32 +0,0 @@
package ru.octol1ttle.knockdowns.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayer;
public class ReviverTracker {
private static final Map<EntityPlayer, List<EntityPlayer>> knockedToReviversMap = new HashMap<>();
public static void startReviving(EntityPlayer knocked, EntityPlayer reviver) {
getRevivers(knocked).add(reviver);
}
public static void stopReviving(EntityPlayer knocked, EntityPlayer reviver) {
getRevivers(knocked).remove(reviver);
}
public static void clearRevivers(EntityPlayer knocked) {
getRevivers(knocked).clear();
}
public static List<EntityPlayer> getRevivers(EntityPlayer knocked) {
return knockedToReviversMap.computeIfAbsent(knocked, player -> new ArrayList<>());
}
public static Set<Map.Entry<EntityPlayer, List<EntityPlayer>>> getAllRevivers() {
return knockedToReviversMap.entrySet();
}
}

View file

@ -4,6 +4,7 @@ import java.util.Objects;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.INBTSerializable;
import ru.octol1ttle.knockdowns.common.util.UniqueOnlyList;
public interface IKnockdownsPlayerData extends INBTSerializable<NBTTagCompound> {
boolean isKnockedDown();
@ -15,6 +16,8 @@ public interface IKnockdownsPlayerData extends INBTSerializable<NBTTagCompound>
int getTicksKnocked();
void setTicksKnocked(int ticksKnocked);
UniqueOnlyList<EntityPlayer> getRevivers();
static IKnockdownsPlayerData get(EntityPlayer player) {
return Objects.requireNonNull(player.getCapability(KnockdownsCapability.CAPABILITY, null));
}

View file

@ -1,7 +1,9 @@
package ru.octol1ttle.knockdowns.common.data;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
import ru.octol1ttle.knockdowns.common.util.UniqueOnlyList;
public class KnockdownsPlayerData implements IKnockdownsPlayerData {
private static final String KEY_KNOCKED_DOWN = "KnockedDown";
@ -10,6 +12,7 @@ public class KnockdownsPlayerData implements IKnockdownsPlayerData {
private boolean knockedDown = false;
private int reviveTimeLeft = KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
private int ticksKnocked = 0;
private final UniqueOnlyList<EntityPlayer> revivers = new UniqueOnlyList<>();
@Override
public boolean isKnockedDown() {
@ -41,6 +44,11 @@ public class KnockdownsPlayerData implements IKnockdownsPlayerData {
this.ticksKnocked = ticksKnocked;
}
@Override
public UniqueOnlyList<EntityPlayer> getRevivers() {
return revivers;
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();

View file

@ -6,12 +6,13 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import ru.octol1ttle.knockdowns.Tags;
import ru.octol1ttle.knockdowns.client.network.KnockdownsClientPacketHandler;
import ru.octol1ttle.knockdowns.common.KnockdownsMod;
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
import ru.octol1ttle.knockdowns.common.network.packets.c2s.PlayerCalloutC2SPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
@ -27,13 +28,14 @@ public class KnockdownsNetwork {
INSTANCE.registerMessage(KnockdownsServerPacketHandler.Callout.class, PlayerCalloutC2SPacket.class, packetId++, Side.SERVER);
INSTANCE.registerMessage(KnockdownsServerPacketHandler.CancelRevive.class, CancelReviveC2SPacket.class, packetId++, Side.SERVER);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.Callout.class, PlayerCalloutS2CPacket.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.PlayerKnockedDown.class, PlayerKnockedDownS2CPacket.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.SynchronizePlayerData.KnockedDown.class, SynchronizePlayerDataS2CPacket.KnockedDown.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.SynchronizePlayerData.ReviveTimeLeft.class, SynchronizePlayerDataS2CPacket.ReviveTimeLeft.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.SynchronizePlayerData.Full.class, SynchronizePlayerDataS2CPacket.Full.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.SynchronizeRevivers.Add.class, SynchronizeReviversS2CPacket.Add.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(KnockdownsClientPacketHandler.SynchronizeRevivers.Remove.class, SynchronizeReviversS2CPacket.Remove.class, packetId++, Side.CLIENT);
IMessageHandler<IMessage, IMessage> clientProxyHandler = (message, ctx) -> KnockdownsMod.clientProxy.handleMessage(message);
INSTANCE.registerMessage(clientProxyHandler, PlayerCalloutS2CPacket.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, PlayerKnockedDownS2CPacket.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.KnockedDown.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.ReviveTimeLeft.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.Full.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, SynchronizeReviversS2CPacket.Add.class, packetId++, Side.CLIENT);
INSTANCE.registerMessage(clientProxyHandler, SynchronizeReviversS2CPacket.Remove.class, packetId++, Side.CLIENT);
}
@SideOnly(Side.CLIENT)

View file

@ -1,13 +1,12 @@
package ru.octol1ttle.knockdowns.common.network;
import java.util.List;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import ru.octol1ttle.knockdowns.common.ReviverTracker;
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
import ru.octol1ttle.knockdowns.common.network.packets.c2s.PlayerCalloutC2SPacket;
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
@ -33,13 +32,14 @@ public class KnockdownsServerPacketHandler {
@Override
public IMessage onMessage(CancelReviveC2SPacket message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
for (Map.Entry<EntityPlayer, List<EntityPlayer>> revivers : ReviverTracker.getAllRevivers()) {
if (revivers.getValue().contains(player)) {
revivers.getValue().remove(player);
for (EntityPlayer knocked : player.world.playerEntities) {
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(knocked).getRevivers();
if (revivers.contains(player)) {
revivers.remove(player);
KnockdownsNetwork.sendToMultiple(
new SynchronizeReviversS2CPacket.Remove(revivers.getKey().getEntityId(), player.getEntityId()),
revivers.getValue(),
(EntityPlayerMP) revivers.getKey()
new SynchronizeReviversS2CPacket.Remove(knocked.getEntityId(), player.getEntityId()),
revivers,
(EntityPlayerMP) knocked
);
break;
}

View file

@ -0,0 +1,23 @@
package ru.octol1ttle.knockdowns.common.util;
import java.util.ArrayList;
public class UniqueOnlyList<T> extends ArrayList<T> {
@Override
public void add(int index, T element) {
throw new IllegalStateException();
}
@Override
public boolean add(T t) {
if (this.contains(t)) {
return false;
}
return super.add(t);
}
@Override
public T set(int index, T element) {
throw new IllegalStateException();
}
}