add the mod
This commit is contained in:
parent
300d509baa
commit
871c10bba3
@ -11,7 +11,7 @@ loader_version=0.14.25
|
|||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=1.0.0
|
mod_version=1.0.0
|
||||||
maven_group=net.touhoudiscord
|
maven_group=net.touhoudiscord
|
||||||
archives_base_name=hardcore-redeploy
|
archives_base_name=hardcore_redeploy
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.91.0+1.20.1
|
fabric_version=0.91.0+1.20.1
|
9
src/main/java/net/touhoudiscord/BuyStationCapable.java
Normal file
9
src/main/java/net/touhoudiscord/BuyStationCapable.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public interface BuyStationCapable {
|
||||||
|
default void hardcoreredeploy_openBuyStationScreen(BlockPos blockPos) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,33 @@
|
|||||||
package net.touhoudiscord;
|
package net.touhoudiscord;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.HorizontalFacingBlock;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.entity.effect.StatusEffect;
|
import net.minecraft.entity.effect.StatusEffect;
|
||||||
|
import net.minecraft.entity.projectile.FireworkRocketEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.GameMode;
|
||||||
import net.touhoudiscord.block.BuyStation;
|
import net.touhoudiscord.block.BuyStation;
|
||||||
import net.touhoudiscord.block.BuyStationEntity;
|
import net.touhoudiscord.block.BuyStationEntity;
|
||||||
import net.touhoudiscord.commands.RedeployPlayerCommand;
|
import net.touhoudiscord.commands.RedeployPlayerCommand;
|
||||||
@ -23,26 +37,104 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import software.bernie.geckolib.GeckoLib;
|
import software.bernie.geckolib.GeckoLib;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.touhoudiscord.HardcoreRedeployConfigHandler.config;
|
||||||
|
import static net.touhoudiscord.block.BuyStation.BUY_STATION_PART;
|
||||||
|
|
||||||
public class HardcoreRedeploy implements ModInitializer {
|
public class HardcoreRedeploy implements ModInitializer {
|
||||||
public static final String MOD_ID = "hardcore-redeploy";
|
public static final String MOD_ID = "hardcore_redeploy";
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger("hardcore-redeploy");
|
public static final Logger LOGGER = LoggerFactory.getLogger("hardcore_redeploy");
|
||||||
|
|
||||||
public static final StatusEffect REDEPLOYING = new RedeployingStatusEffect();
|
public static final StatusEffect REDEPLOYING = new RedeployingStatusEffect();
|
||||||
public static final Block BUY_STATION = Registry.register(Registries.BLOCK, new Identifier(HardcoreRedeploy.MOD_ID, "buy_station"), new BuyStation(FabricBlockSettings.copyOf(Blocks.HOPPER).nonOpaque()));
|
public static final Block BUY_STATION = Registry.register(Registries.BLOCK, new Identifier(HardcoreRedeploy.MOD_ID, "buy_station"), new BuyStation(FabricBlockSettings.create().nonOpaque().requiresTool().resistance(6).hardness(3)));
|
||||||
public static final Item BUY_STATION_ITEM = Registry.register(Registries.ITEM, new Identifier(HardcoreRedeploy.MOD_ID, "buy_station"), new BuyStationItem(HardcoreRedeploy.BUY_STATION, new FabricItemSettings()));
|
public static final Item BUY_STATION_ITEM = Registry.register(Registries.ITEM, new Identifier(HardcoreRedeploy.MOD_ID, "buy_station"), new BuyStationItem(HardcoreRedeploy.BUY_STATION, new FabricItemSettings()));
|
||||||
|
public static final Identifier BUY_STATION_SOUND_ID = new Identifier(HardcoreRedeploy.MOD_ID, "buy_station");
|
||||||
|
public static SoundEvent BUY_STATION_SOUND_EVENT = SoundEvent.of(BUY_STATION_SOUND_ID);
|
||||||
public static BlockEntityType<BuyStationEntity> BUY_STATION_ENTITY;
|
public static BlockEntityType<BuyStationEntity> BUY_STATION_ENTITY;
|
||||||
|
|
||||||
|
public static final Identifier SEND_REVIVES_UPDATE = new Identifier(HardcoreRedeploy.MOD_ID, "send_revives_update");
|
||||||
|
public static final Identifier REQUEST_REVIVE = new Identifier(HardcoreRedeploy.MOD_ID, "request_revive");
|
||||||
|
public static final Identifier SEND_REVIVE = new Identifier(HardcoreRedeploy.MOD_ID, "send_revive");
|
||||||
|
public static final Identifier SYNC_CONFIG = new Identifier(HardcoreRedeploy.MOD_ID, "sync_config");
|
||||||
|
|
||||||
|
private static final ItemStack firework;
|
||||||
|
static {
|
||||||
|
firework = new ItemStack(Registries.ITEM.get(new Identifier("minecraft", "firework_rocket")));
|
||||||
|
NbtCompound nbt = new NbtCompound();
|
||||||
|
nbt.putByte("Flight", (byte)3);
|
||||||
|
firework.setSubNbt("Fireworks", nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
LOGGER.info("Initializing Hardcore Redeploy");
|
LOGGER.info("Initializing Hardcore Redeploy");
|
||||||
|
|
||||||
GeckoLib.initialize();
|
GeckoLib.initialize();
|
||||||
|
|
||||||
|
ServerPlayNetworking.registerGlobalReceiver(REQUEST_REVIVE, (server, player, handler, buf, responseSender) -> {
|
||||||
|
ServerPlayerEntity spectator = server.getPlayerManager().getPlayer(buf.readUuid());
|
||||||
|
if (spectator == null) return;
|
||||||
|
|
||||||
|
BlockPos blockPos = buf.readBlockPos();
|
||||||
|
BlockState invokingBlock = player.getWorld().getBlockState(blockPos);
|
||||||
|
|
||||||
|
if (invokingBlock.getBlock() instanceof BuyStation && player.getPos().isInRange(blockPos.toCenterPos(), 5)) {
|
||||||
|
|
||||||
|
int cost = config.baseCost+config.additiveCost*RedeployStateSaver.getPlayerState(spectator).timesRevived;
|
||||||
|
boolean isCreative = player.interactionManager.getGameMode() == GameMode.CREATIVE;
|
||||||
|
if (!isCreative && player.experienceLevel < cost) return;
|
||||||
|
|
||||||
|
Vec3d fireworkPos = blockPos.toCenterPos();
|
||||||
|
BlockState blockState = player.getWorld().getBlockState(blockPos);
|
||||||
|
Direction offset = blockState.get(HorizontalFacingBlock.FACING).rotateYClockwise();
|
||||||
|
if (blockState.get(BUY_STATION_PART) == BuyStation.BuyStationPart.AUX) offset = offset.getOpposite();
|
||||||
|
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(player.getWorld(), fireworkPos.x+offset.getOffsetX()/2., fireworkPos.y, fireworkPos.z+offset.getOffsetZ()/2., firework);
|
||||||
|
player.getWorld().spawnEntity(fireworkRocketEntity);
|
||||||
|
|
||||||
|
if (!isCreative) player.setExperienceLevel(player.experienceLevel-cost);
|
||||||
|
((TimerAccess) server).hardcoreredeploy_redeployInTicks(spectator, player, 60L);
|
||||||
|
server.execute(() -> {
|
||||||
|
PacketByteBuf buf1 = PacketByteBufs.create();
|
||||||
|
ServerPlayNetworking.send(spectator, SEND_REVIVE, buf1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||||
|
syncConfig(server, handler.getPlayer());
|
||||||
|
|
||||||
|
RedeployStateSaver.getServerState(server).players.forEach((uuid, playerData) -> {
|
||||||
|
syncRevives(server, handler.getPlayer(), uuid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
BUY_STATION_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE,
|
BUY_STATION_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE,
|
||||||
new Identifier(HardcoreRedeploy.MOD_ID, "buy_station_entity"),
|
new Identifier(HardcoreRedeploy.MOD_ID, "buy_station_entity"),
|
||||||
FabricBlockEntityTypeBuilder.create(BuyStationEntity::new,
|
FabricBlockEntityTypeBuilder.create(BuyStationEntity::new,
|
||||||
HardcoreRedeploy.BUY_STATION).build());
|
HardcoreRedeploy.BUY_STATION).build());
|
||||||
Registry.register(Registries.STATUS_EFFECT, new Identifier(HardcoreRedeploy.MOD_ID, "redeploying"), REDEPLOYING);
|
Registry.register(Registries.STATUS_EFFECT, new Identifier(HardcoreRedeploy.MOD_ID, "redeploying"), REDEPLOYING);
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> RedeployPlayerCommand.register(dispatcher));
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> RedeployPlayerCommand.register(dispatcher));
|
||||||
|
Registry.register(Registries.SOUND_EVENT, BUY_STATION_SOUND_ID, BUY_STATION_SOUND_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void syncConfig(MinecraftServer server, ServerPlayerEntity receiver) {
|
||||||
|
PacketByteBuf buf = PacketByteBufs.create();
|
||||||
|
buf.writeInt(HardcoreRedeployConfigHandler.config.baseCost);
|
||||||
|
buf.writeInt(HardcoreRedeployConfigHandler.config.additiveCost);
|
||||||
|
server.execute(() -> {
|
||||||
|
ServerPlayNetworking.send(receiver, SYNC_CONFIG, buf);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void syncRevives(MinecraftServer server, ServerPlayerEntity receiver, UUID uuid) {
|
||||||
|
PlayerData playerData = RedeployStateSaver.getPlayerState(server, uuid);
|
||||||
|
PacketByteBuf buf = PacketByteBufs.create();
|
||||||
|
buf.writeUuid(uuid);
|
||||||
|
buf.writeInt(playerData.timesRevived);
|
||||||
|
server.execute(() -> {
|
||||||
|
ServerPlayNetworking.send(receiver, SEND_REVIVES_UPDATE, buf);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,45 @@
|
|||||||
package net.touhoudiscord;
|
package net.touhoudiscord;
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
|
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
|
||||||
|
import net.touhoudiscord.HardcoreRedeployConfigHandler.HardcoreRedeployConfig;
|
||||||
import net.touhoudiscord.block.client.BuyStationRenderer;
|
import net.touhoudiscord.block.client.BuyStationRenderer;
|
||||||
|
import net.touhoudiscord.screen.RedeployingScreen;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
public class HardcoreRedeployClient implements ClientModInitializer {
|
public class HardcoreRedeployClient implements ClientModInitializer {
|
||||||
|
|
||||||
|
public static HashMap<UUID, Integer> reviveMap = new HashMap<>();
|
||||||
|
public static HardcoreRedeployConfig serverConfig = HardcoreRedeployConfigHandler.config;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
BlockEntityRendererFactories.register(HardcoreRedeploy.BUY_STATION_ENTITY, BuyStationRenderer::new);
|
BlockEntityRendererFactories.register(HardcoreRedeploy.BUY_STATION_ENTITY, BuyStationRenderer::new);
|
||||||
|
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(HardcoreRedeploy.SEND_REVIVES_UPDATE, (client, handler, buf, responseSender) -> {
|
||||||
|
reviveMap.put(buf.readUuid(), buf.readInt());
|
||||||
|
|
||||||
|
HardcoreRedeploy.LOGGER.info("Synced player revives");
|
||||||
|
});
|
||||||
|
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(HardcoreRedeploy.SEND_REVIVE, (client, handler, buf, responseSender) -> {
|
||||||
|
client.execute(() -> {
|
||||||
|
client.setScreen(new RedeployingScreen(6*20));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(HardcoreRedeploy.SYNC_CONFIG, (client, handler, buf, responseSender) -> {
|
||||||
|
serverConfig = new HardcoreRedeployConfig();
|
||||||
|
serverConfig.baseCost = buf.readInt();
|
||||||
|
serverConfig.additiveCost = buf.readInt();
|
||||||
|
|
||||||
|
HardcoreRedeploy.LOGGER.info("Synced server config");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
public class HardcoreRedeployConfigHandler {
|
||||||
|
private static final Path configPath = FabricLoader.getInstance().getConfigDir().resolve("hardcore_redeploy.json");
|
||||||
|
private static final Gson gson = new Gson();
|
||||||
|
public static HardcoreRedeployConfig config = readOrCreateConfig();
|
||||||
|
|
||||||
|
public HardcoreRedeployConfigHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HardcoreRedeployConfig readOrCreateConfig() {
|
||||||
|
try {
|
||||||
|
return gson.fromJson(Files.readString(configPath), HardcoreRedeployConfig.class);
|
||||||
|
}
|
||||||
|
catch(IOException e) {
|
||||||
|
HardcoreRedeployConfig newConfig = new HardcoreRedeployConfig();
|
||||||
|
try {
|
||||||
|
Files.writeString(configPath, gson.toJson(newConfig), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
return newConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HardcoreRedeployConfig {
|
||||||
|
public int baseCost = 10;
|
||||||
|
public int additiveCost = 10;
|
||||||
|
HardcoreRedeployConfig(){}
|
||||||
|
}
|
||||||
|
}
|
5
src/main/java/net/touhoudiscord/PlayerData.java
Normal file
5
src/main/java/net/touhoudiscord/PlayerData.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
public class PlayerData {
|
||||||
|
public int timesRevived = 0;
|
||||||
|
}
|
13
src/main/java/net/touhoudiscord/PlayerTimer.java
Normal file
13
src/main/java/net/touhoudiscord/PlayerTimer.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerTimer {
|
||||||
|
public UUID target;
|
||||||
|
public Long ticks;
|
||||||
|
|
||||||
|
public PlayerTimer(UUID target, Long ticks) {
|
||||||
|
this.target = target;
|
||||||
|
this.ticks = ticks;
|
||||||
|
}
|
||||||
|
}
|
@ -6,8 +6,15 @@ import net.minecraft.world.GameMode;
|
|||||||
|
|
||||||
public class RedeployPlayer {
|
public class RedeployPlayer {
|
||||||
public static void redeploy(ServerPlayerEntity spectator, ServerPlayerEntity target) {
|
public static void redeploy(ServerPlayerEntity spectator, ServerPlayerEntity target) {
|
||||||
|
if (!(spectator.interactionManager.getGameMode() == GameMode.SPECTATOR)) return;
|
||||||
|
|
||||||
if (!target.getServerWorld().getDimension().hasCeiling()) spectator.addStatusEffect(new StatusEffectInstance(HardcoreRedeploy.REDEPLOYING, 20*20, 0));
|
if (!target.getServerWorld().getDimension().hasCeiling()) spectator.addStatusEffect(new StatusEffectInstance(HardcoreRedeploy.REDEPLOYING, 20*20, 0));
|
||||||
spectator.teleport(target.getServerWorld(), target.getPos().x, target.getServerWorld().getDimension().hasCeiling() ? target.getPos().y : 320, target.getPos().z, 0, 30);
|
spectator.teleport(target.getServerWorld(), target.getPos().x, target.getServerWorld().getDimension().hasCeiling() ? target.getPos().y : 320, target.getPos().z, 0, 30);
|
||||||
spectator.changeGameMode(GameMode.SURVIVAL);
|
spectator.changeGameMode(GameMode.SURVIVAL);
|
||||||
|
|
||||||
|
RedeployStateSaver.getPlayerState(spectator).timesRevived++;
|
||||||
|
spectator.server.getPlayerManager().getPlayerList().forEach(player -> {
|
||||||
|
HardcoreRedeploy.syncRevives(player.server, player, spectator.getUuid());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
src/main/java/net/touhoudiscord/RedeployStateSaver.java
Normal file
74
src/main/java/net/touhoudiscord/RedeployStateSaver.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.PersistentState;
|
||||||
|
import net.minecraft.world.PersistentStateManager;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class RedeployStateSaver extends PersistentState {
|
||||||
|
|
||||||
|
public HashMap<UUID, PlayerData> players = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NbtCompound writeNbt(NbtCompound nbt) {
|
||||||
|
|
||||||
|
NbtCompound playersNbt = new NbtCompound();
|
||||||
|
players.forEach((uuid, playerData) -> {
|
||||||
|
NbtCompound playerNbt = new NbtCompound();
|
||||||
|
|
||||||
|
playerNbt.putInt("timesRevived", playerData.timesRevived);
|
||||||
|
|
||||||
|
playersNbt.put(uuid.toString(), playerNbt);
|
||||||
|
});
|
||||||
|
nbt.put("players", playersNbt);
|
||||||
|
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RedeployStateSaver createFromNbt(NbtCompound tag) {
|
||||||
|
RedeployStateSaver state = new RedeployStateSaver();
|
||||||
|
|
||||||
|
NbtCompound playersNbt = tag.getCompound("players");
|
||||||
|
playersNbt.getKeys().forEach(key -> {
|
||||||
|
PlayerData playerData = new PlayerData();
|
||||||
|
|
||||||
|
playerData.timesRevived = playersNbt.getCompound(key).getInt("timesRevived");
|
||||||
|
|
||||||
|
UUID uuid = UUID.fromString(key);
|
||||||
|
state.players.put(uuid, playerData);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RedeployStateSaver getServerState(MinecraftServer server) {
|
||||||
|
PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager();
|
||||||
|
|
||||||
|
RedeployStateSaver state = persistentStateManager.getOrCreate(RedeployStateSaver::createFromNbt, RedeployStateSaver::new, HardcoreRedeploy.MOD_ID);
|
||||||
|
|
||||||
|
state.markDirty();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerData getPlayerState(LivingEntity player) {
|
||||||
|
RedeployStateSaver serverState = getServerState(player.getWorld().getServer());
|
||||||
|
|
||||||
|
PlayerData playerState = serverState.players.computeIfAbsent(player.getUuid(), uuid -> new PlayerData());
|
||||||
|
|
||||||
|
return playerState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerData getPlayerState(MinecraftServer server, UUID uuid) {
|
||||||
|
RedeployStateSaver serverState = getServerState(server);
|
||||||
|
|
||||||
|
PlayerData playerState = serverState.players.computeIfAbsent(uuid, i -> new PlayerData());
|
||||||
|
|
||||||
|
return playerState;
|
||||||
|
}
|
||||||
|
}
|
7
src/main/java/net/touhoudiscord/TimerAccess.java
Normal file
7
src/main/java/net/touhoudiscord/TimerAccess.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package net.touhoudiscord;
|
||||||
|
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
|
||||||
|
public interface TimerAccess {
|
||||||
|
void hardcoreredeploy_redeployInTicks(ServerPlayerEntity spectator, ServerPlayerEntity target, Long ticks);
|
||||||
|
}
|
@ -1,31 +1,144 @@
|
|||||||
package net.touhoudiscord.block;
|
package net.touhoudiscord.block;
|
||||||
|
|
||||||
import net.minecraft.block.BlockRenderType;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.BlockWithEntity;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.state.StateManager;
|
||||||
|
import net.minecraft.state.property.EnumProperty;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.StringIdentifiable;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldEvents;
|
||||||
import net.minecraft.world.WorldView;
|
import net.minecraft.world.WorldView;
|
||||||
|
import net.touhoudiscord.BuyStationCapable;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class BuyStation extends BlockWithEntity {
|
public class BuyStation extends BlockWithEntity {
|
||||||
|
public static final EnumProperty<BuyStationPart> BUY_STATION_PART = EnumProperty.of("part", BuyStationPart.class);
|
||||||
|
|
||||||
|
protected static final VoxelShape NORTH_SHAPE = Block.createCuboidShape(1.0, 0.0, 1.0, 16.0, 12.0, 15.0);
|
||||||
|
protected static final VoxelShape SOUTH_SHAPE = Block.createCuboidShape(0.0, 0.0, 1.0, 15.0, 12.0, 15.0);
|
||||||
|
protected static final VoxelShape WEST_SHAPE = Block.createCuboidShape(1.0, 0.0, 0.0, 15.0, 12.0, 15.0);
|
||||||
|
protected static final VoxelShape EAST_SHAPE = Block.createCuboidShape(1.0, 0.0, 1.0, 15.0, 12.0, 16.0);
|
||||||
|
|
||||||
public BuyStation(Settings settings) {
|
public BuyStation(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
this.setDefaultState(this.getDefaultState()
|
||||||
|
.with(HorizontalFacingBlock.FACING, Direction.NORTH)
|
||||||
|
.with(BUY_STATION_PART, BuyStationPart.MAIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||||
|
return this.getDefaultState().with(HorizontalFacingBlock.FACING, ctx.getHorizontalPlayerFacing());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
|
||||||
|
super.onPlaced(world, pos, state, placer, itemStack);
|
||||||
|
if (!world.isClient) {
|
||||||
|
BlockPos blockPos = pos.offset(state.get(HorizontalFacingBlock.FACING).rotateYClockwise());
|
||||||
|
world.setBlockState(blockPos, state.with(BUY_STATION_PART, BuyStationPart.AUX), Block.NOTIFY_ALL);
|
||||||
|
world.updateNeighbors(pos, Blocks.AIR);
|
||||||
|
state.updateNeighbors(world, pos, Block.NOTIFY_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||||
|
if (world.isClient()) {
|
||||||
|
super.onBreak(world, pos, state, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuyStationPart part = state.get(BUY_STATION_PART);
|
||||||
|
if (part == BuyStationPart.MAIN) {
|
||||||
|
BlockPos otherpos = pos.offset(state.get(HorizontalFacingBlock.FACING).rotateYClockwise());
|
||||||
|
BlockState otherstate = world.getBlockState(otherpos);
|
||||||
|
if (otherstate.getBlock() == this) {
|
||||||
|
world.setBlockState(otherpos, Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL);
|
||||||
|
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, otherpos, Block.getRawIdFromState(otherstate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (part == BuyStationPart.AUX) {
|
||||||
|
BlockPos otherpos = pos.offset(state.get(HorizontalFacingBlock.FACING).rotateYCounterclockwise());
|
||||||
|
BlockState otherstate = world.getBlockState(otherpos);
|
||||||
|
if (otherstate.getBlock() == this) {
|
||||||
|
world.setBlockState(otherpos, Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL);
|
||||||
|
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, otherpos, Block.getRawIdFromState(otherstate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
|
Direction direction = state.get(HorizontalFacingBlock.FACING);
|
||||||
|
BuyStationPart part = state.get(BUY_STATION_PART);
|
||||||
|
if (part == BuyStationPart.AUX) direction = direction.getOpposite();
|
||||||
|
return switch (direction) {
|
||||||
|
default -> NORTH_SHAPE;
|
||||||
|
case SOUTH -> SOUTH_SHAPE;
|
||||||
|
case WEST -> WEST_SHAPE;
|
||||||
|
case EAST -> EAST_SHAPE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
|
Block block = world.getBlockState(pos).getBlock();
|
||||||
|
if (block instanceof BuyStation) {
|
||||||
|
((BuyStationCapable) player).hardcoreredeploy_openBuyStationScreen(pos);
|
||||||
|
return ActionResult.success(world.isClient);
|
||||||
|
} else {
|
||||||
|
return ActionResult.PASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(HorizontalFacingBlock.FACING, BUY_STATION_PART);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
return new BuyStationEntity(pos, state);
|
return state.get(BUY_STATION_PART) == BuyStationPart.MAIN ? new BuyStationEntity(pos, state) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockRenderType getRenderType(BlockState state) {
|
public BlockRenderType getRenderType(BlockState state) {
|
||||||
return BlockRenderType.MODEL;
|
return state.get(BUY_STATION_PART) == BuyStationPart.MAIN ? BlockRenderType.MODEL : BlockRenderType.INVISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
||||||
return super.canPlaceAt(state, world, pos);
|
return world.getBlockState(pos.offset(state.get(HorizontalFacingBlock.FACING).rotateYClockwise())).isReplaceable() && super.canPlaceAt(state, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum BuyStationPart implements StringIdentifiable {
|
||||||
|
MAIN("main"),
|
||||||
|
AUX("aux");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
BuyStationPart(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String asString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,21 @@ package net.touhoudiscord.block;
|
|||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.touhoudiscord.HardcoreRedeploy;
|
import net.touhoudiscord.HardcoreRedeploy;
|
||||||
import software.bernie.geckolib.animatable.GeoBlockEntity;
|
import software.bernie.geckolib.animatable.GeoBlockEntity;
|
||||||
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
||||||
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
||||||
import software.bernie.geckolib.core.animation.*;
|
import software.bernie.geckolib.core.animation.AnimatableManager;
|
||||||
|
import software.bernie.geckolib.core.animation.AnimationController;
|
||||||
|
import software.bernie.geckolib.core.animation.RawAnimation;
|
||||||
|
import software.bernie.geckolib.util.ClientUtils;
|
||||||
import software.bernie.geckolib.util.RenderUtils;
|
import software.bernie.geckolib.util.RenderUtils;
|
||||||
|
|
||||||
public class BuyStationEntity extends BlockEntity implements GeoBlockEntity {
|
public class BuyStationEntity extends BlockEntity implements GeoBlockEntity {
|
||||||
private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
||||||
|
|
||||||
private static final RawAnimation OPEN = RawAnimation.begin().thenPlay("animation.model.open").thenLoop("animation.model.idle");
|
private static final RawAnimation OPEN = RawAnimation.begin().thenPlay("animation.model.open").thenLoop("animation.model.idle");
|
||||||
private static final RawAnimation CLOSE = RawAnimation.begin().thenPlay("animation.model.close");
|
private static final RawAnimation CLOSE = RawAnimation.begin().thenPlay("animation.model.close");
|
||||||
@ -26,11 +30,20 @@ public class BuyStationEntity extends BlockEntity implements GeoBlockEntity {
|
|||||||
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
||||||
controllers.add(new AnimationController<>(this, "buystationcontroller", 0, state -> {
|
controllers.add(new AnimationController<>(this, "buystationcontroller", 0, state -> {
|
||||||
Vec3d pos = state.getAnimatable().getPos().toCenterPos();
|
Vec3d pos = state.getAnimatable().getPos().toCenterPos();
|
||||||
if (state.getAnimatable().getWorld().getClosestPlayer(pos.x, pos.y, pos.z, 5, false) instanceof PlayerEntity)
|
if (state.getAnimatable().getWorld().getClosestPlayer(pos.x, pos.y, pos.z, 5, false) instanceof PlayerEntity) {
|
||||||
return state.setAndContinue(OPEN);
|
return state.setAndContinue(OPEN);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return state.setAndContinue(CLOSE);
|
return state.setAndContinue(CLOSE);
|
||||||
}));
|
}
|
||||||
|
})
|
||||||
|
.setSoundKeyframeHandler(event -> {
|
||||||
|
PlayerEntity player = ClientUtils.getClientPlayer();
|
||||||
|
|
||||||
|
if (player != null) {
|
||||||
|
player.getWorld().playSound(player, this.getPos(), HardcoreRedeploy.BUY_STATION_SOUND_EVENT, SoundCategory.BLOCKS, 1, 1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package net.touhoudiscord.block.client;
|
package net.touhoudiscord.block.client;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.touhoudiscord.HardcoreRedeploy;
|
import net.touhoudiscord.HardcoreRedeploy;
|
||||||
import net.touhoudiscord.block.BuyStationEntity;
|
import net.touhoudiscord.block.BuyStationEntity;
|
||||||
import software.bernie.geckolib.model.GeoModel;
|
import software.bernie.geckolib.model.GeoModel;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
public class BuyStationModel extends GeoModel<BuyStationEntity> {
|
public class BuyStationModel extends GeoModel<BuyStationEntity> {
|
||||||
@Override
|
@Override
|
||||||
public Identifier getModelResource(BuyStationEntity animatable) {
|
public Identifier getModelResource(BuyStationEntity animatable) {
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
package net.touhoudiscord.block.client;
|
package net.touhoudiscord.block.client;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.block.HorizontalFacingBlock;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
|
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.touhoudiscord.block.BuyStationEntity;
|
import net.touhoudiscord.block.BuyStationEntity;
|
||||||
|
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||||
import software.bernie.geckolib.renderer.GeoBlockRenderer;
|
import software.bernie.geckolib.renderer.GeoBlockRenderer;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
public class BuyStationRenderer extends GeoBlockRenderer<BuyStationEntity> {
|
public class BuyStationRenderer extends GeoBlockRenderer<BuyStationEntity> {
|
||||||
public BuyStationRenderer(BlockEntityRendererFactory.Context context) {
|
public BuyStationRenderer(BlockEntityRendererFactory.Context context) {
|
||||||
super(new BuyStationModel());
|
super(new BuyStationModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRender(MatrixStack poseStack, BuyStationEntity animatable, BakedGeoModel model, VertexConsumerProvider bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
|
||||||
|
Direction direction = animatable.getCachedState().get(HorizontalFacingBlock.FACING).rotateYClockwise();
|
||||||
|
poseStack.translate(direction.getOffsetX()/2., 0, direction.getOffsetZ()/2.);
|
||||||
|
super.preRender(poseStack, animatable, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ import net.minecraft.server.command.ServerCommandSource;
|
|||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.world.GameMode;
|
import net.minecraft.world.GameMode;
|
||||||
import net.touhoudiscord.HardcoreRedeploy;
|
|
||||||
import net.touhoudiscord.RedeployPlayer;
|
import net.touhoudiscord.RedeployPlayer;
|
||||||
|
|
||||||
import static net.minecraft.server.command.CommandManager.*;
|
import static net.minecraft.server.command.CommandManager.argument;
|
||||||
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
|
|
||||||
public class RedeployPlayerCommand {
|
public class RedeployPlayerCommand {
|
||||||
|
|
||||||
@ -36,7 +36,5 @@ public class RedeployPlayerCommand {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
HardcoreRedeploy.LOGGER.info("Registered RedeployPlayer command");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@ import software.bernie.geckolib.animatable.SingletonGeoAnimatable;
|
|||||||
import software.bernie.geckolib.animatable.client.RenderProvider;
|
import software.bernie.geckolib.animatable.client.RenderProvider;
|
||||||
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
||||||
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
||||||
import software.bernie.geckolib.core.animation.*;
|
import software.bernie.geckolib.core.animation.AnimatableManager;
|
||||||
|
import software.bernie.geckolib.core.animation.AnimationController;
|
||||||
import software.bernie.geckolib.core.object.PlayState;
|
import software.bernie.geckolib.core.object.PlayState;
|
||||||
import software.bernie.geckolib.util.RenderUtils;
|
import software.bernie.geckolib.util.RenderUtils;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class BuyStationItem extends BlockItem implements GeoItem {
|
public class BuyStationItem extends BlockItem implements GeoItem {
|
||||||
private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
||||||
private final Supplier<Object> renderProvider = GeoItem.makeRenderer(this);
|
private final Supplier<Object> renderProvider = GeoItem.makeRenderer(this);
|
||||||
|
|
||||||
public BuyStationItem(Block block, Settings settings) {
|
public BuyStationItem(Block block, Settings settings) {
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package net.touhoudiscord.item.client;
|
package net.touhoudiscord.item.client;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.touhoudiscord.HardcoreRedeploy;
|
import net.touhoudiscord.HardcoreRedeploy;
|
||||||
import net.touhoudiscord.item.BuyStationItem;
|
import net.touhoudiscord.item.BuyStationItem;
|
||||||
import software.bernie.geckolib.model.GeoModel;
|
import software.bernie.geckolib.model.GeoModel;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
public class BuyStationItemModel extends GeoModel<BuyStationItem> {
|
public class BuyStationItemModel extends GeoModel<BuyStationItem> {
|
||||||
@Override
|
@Override
|
||||||
public Identifier getModelResource(BuyStationItem animatable) {
|
public Identifier getModelResource(BuyStationItem animatable) {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package net.touhoudiscord.item.client;
|
package net.touhoudiscord.item.client;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
import net.touhoudiscord.item.BuyStationItem;
|
import net.touhoudiscord.item.BuyStationItem;
|
||||||
import software.bernie.geckolib.renderer.GeoItemRenderer;
|
import software.bernie.geckolib.renderer.GeoItemRenderer;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
public class BuyStationItemRenderer extends GeoItemRenderer<BuyStationItem> {
|
public class BuyStationItemRenderer extends GeoItemRenderer<BuyStationItem> {
|
||||||
public BuyStationItemRenderer() {
|
public BuyStationItemRenderer() {
|
||||||
super(new BuyStationItemModel());
|
super(new BuyStationItemModel());
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.touhoudiscord.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.touhoudiscord.BuyStationCapable;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(PlayerEntity.class)
|
||||||
|
public class BuyStationScreenMixin implements BuyStationCapable {
|
||||||
|
@Override
|
||||||
|
public void hardcoreredeploy_openBuyStationScreen(BlockPos blockPos) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package net.touhoudiscord.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.touhoudiscord.BuyStationCapable;
|
||||||
|
import net.touhoudiscord.screen.BuyStationScreen;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(ClientPlayerEntity.class)
|
||||||
|
public class ClientBuyStationScreenMixin implements BuyStationCapable {
|
||||||
|
@Shadow @Final protected MinecraftClient client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hardcoreredeploy_openBuyStationScreen(BlockPos blockPos) {
|
||||||
|
this.client.setScreen(new BuyStationScreen(blockPos));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.touhoudiscord.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.touhoudiscord.PlayerTimer;
|
||||||
|
import net.touhoudiscord.RedeployPlayer;
|
||||||
|
import net.touhoudiscord.TimerAccess;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Mixin(MinecraftServer.class)
|
||||||
|
public abstract class RedeployTimerMixin implements TimerAccess {
|
||||||
|
@Shadow public abstract PlayerManager getPlayerManager();
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private final HashMap<UUID, PlayerTimer> playerTimers = new HashMap<>();
|
||||||
|
|
||||||
|
@Inject(method = "tick", at = @At("TAIL"))
|
||||||
|
private void onTick(CallbackInfo ci) {
|
||||||
|
this.playerTimers.forEach((uuid, timer) -> {
|
||||||
|
if (--timer.ticks == 0L) {
|
||||||
|
ServerPlayerEntity spectator = this.getPlayerManager().getPlayer(uuid);
|
||||||
|
ServerPlayerEntity target = this.getPlayerManager().getPlayer(timer.target);
|
||||||
|
if (spectator != null && target != null) RedeployPlayer.redeploy(spectator, target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hardcoreredeploy_redeployInTicks(ServerPlayerEntity spectator, ServerPlayerEntity target, Long ticks) {
|
||||||
|
this.playerTimers.put(spectator.getUuid(), new PlayerTimer(target.getUuid(), ticks));
|
||||||
|
}
|
||||||
|
}
|
125
src/main/java/net/touhoudiscord/screen/BuyStationScreen.java
Normal file
125
src/main/java/net/touhoudiscord/screen/BuyStationScreen.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package net.touhoudiscord.screen;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.Element;
|
||||||
|
import net.minecraft.client.gui.Selectable;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||||
|
import net.minecraft.client.gui.widget.ElementListWidget;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.GameMode;
|
||||||
|
import net.touhoudiscord.HardcoreRedeploy;
|
||||||
|
import net.touhoudiscord.HardcoreRedeployClient;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.touhoudiscord.HardcoreRedeployClient.serverConfig;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BuyStationScreen extends Screen {
|
||||||
|
private final BlockPos blockPos;
|
||||||
|
|
||||||
|
private PlayerListWidget playerList;
|
||||||
|
|
||||||
|
public BuyStationScreen(BlockPos blockPos) {
|
||||||
|
super(Text.literal("Buy Station"));
|
||||||
|
this.blockPos = blockPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
playerList = new PlayerListWidget(client, width+38, height, height/2-58, height/2+84, 28);
|
||||||
|
client.player.networkHandler.getListedPlayerListEntries().forEach(entry -> {
|
||||||
|
if (entry.getGameMode() == GameMode.SPECTATOR) playerList.addPlayerEntry(new PlayerListEntry(Text.literal(entry.getProfile().getName()), entry.getProfile().getId()));
|
||||||
|
});
|
||||||
|
|
||||||
|
addDrawableChild(playerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
renderBackground(context);
|
||||||
|
context.fill(width/2-93, height/2-84, width/2+93, height/2+84, 0x8F_000000);
|
||||||
|
context.fill(width/2-93, height/2-84, width/2+93, height/2-58, 0xA0_000000);
|
||||||
|
context.getMatrices().push();
|
||||||
|
context.getMatrices().scale(1.5f, 1.5f, 1f);
|
||||||
|
context.drawText(textRenderer, Text.literal("Buy Station"), Math.round((width/2-80)/1.5f), Math.round((height/2-75)/1.5f), 0xFF_73c0e7, false);
|
||||||
|
context.getMatrices().pop();
|
||||||
|
Text money = Text.literal("$").append(Text.literal(String.valueOf(client.player.experienceLevel*100)));
|
||||||
|
context.drawText(textRenderer, money, width/2+80-textRenderer.getWidth(money), height/2-72, 0xFF_FFFFFF, false);
|
||||||
|
playerList.render(context, mouseX, mouseY, delta);
|
||||||
|
super.render(context, mouseX, mouseY, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldPause() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PlayerListWidget extends ElementListWidget<PlayerListEntry> {
|
||||||
|
public PlayerListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) {
|
||||||
|
super(minecraftClient, i, j, k, l, m);
|
||||||
|
this.setRenderBackground(false);
|
||||||
|
this.setRenderHorizontalShadows(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayerEntry(PlayerListEntry entry) {
|
||||||
|
this.addEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PlayerListEntry extends ElementListWidget.Entry<PlayerListEntry> {
|
||||||
|
private final ButtonWidget button;
|
||||||
|
private final Text name;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public PlayerListEntry(Text name, UUID uuid) {
|
||||||
|
this.button = ButtonWidget.builder(name, button1 -> {
|
||||||
|
PacketByteBuf buf = PacketByteBufs.create();
|
||||||
|
buf.writeUuid(uuid);
|
||||||
|
buf.writeBlockPos(blockPos);
|
||||||
|
ClientPlayNetworking.send(HardcoreRedeploy.REQUEST_REVIVE, buf);
|
||||||
|
client.setScreen(null);
|
||||||
|
})
|
||||||
|
.position(4,2)
|
||||||
|
.size(178, 18)
|
||||||
|
.build();
|
||||||
|
this.name = name;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends Selectable> selectableChildren() {
|
||||||
|
return List.of(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends Element> children() {
|
||||||
|
return List.of(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
|
||||||
|
button.setX(x);
|
||||||
|
button.setY(y);
|
||||||
|
boolean isHovered = mouseX >= x && mouseX <= x+178 && mouseY >= y && mouseY <= y+18;
|
||||||
|
Integer revives = HardcoreRedeployClient.reviveMap.get(this.uuid);
|
||||||
|
int cost = serverConfig.baseCost+(revives == null ? 0 : revives)*serverConfig.additiveCost;
|
||||||
|
int backgroundColor = ((isHovered ? 0x30 : 0x20) << 24) +
|
||||||
|
((client.player.experienceLevel >= cost) ? 0x2397d1 : 0xa3a3a3);
|
||||||
|
context.fill(x, y, x+178, y+18, backgroundColor);
|
||||||
|
context.drawText(textRenderer, button.getMessage(), x+4, y+5, 0xFF_73c0e7, false);
|
||||||
|
Text money = Text.literal("$").append(Text.literal(String.valueOf(cost*100)));
|
||||||
|
context.drawText(textRenderer, money, x+178-4-textRenderer.getWidth(money), y+5, 0xFF_7efc20, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package net.touhoudiscord.screen;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public class RedeployingScreen extends Screen {
|
||||||
|
|
||||||
|
private final float duration;
|
||||||
|
private float time;
|
||||||
|
|
||||||
|
public RedeployingScreen(float duration) {
|
||||||
|
super(Text.empty());
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
time += delta;
|
||||||
|
context.fill(0, 0, width, height, Math.round((1-Math.abs((float)Math.sin(((time/(duration/2))-1)*(Math.PI/2))))*255)<<24);
|
||||||
|
super.render(context, mouseX, mouseY, delta);
|
||||||
|
if (time > duration) client.setScreen(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldPause() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCloseOnEsc() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"variants": {
|
|
||||||
"": { "model": "hardcore-redeploy:block/buy_station" }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"block.hardcore-redeploy.buy_station": "Buy Station",
|
|
||||||
"effect.hardcore-redeploy.redeploying": "Redeploying"
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"credit": "Made with Blockbench",
|
|
||||||
"parent": "builtin/entity",
|
|
||||||
"texture_size": [
|
|
||||||
64,
|
|
||||||
64
|
|
||||||
],
|
|
||||||
"textures": {
|
|
||||||
"particle": "minecraft:block/hopper_outside"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"parent": "hardcore-redeploy:block/buy_station"
|
|
||||||
}
|
|
@ -28,7 +28,7 @@
|
|||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
},
|
},
|
||||||
"0.25": {
|
"0.25": {
|
||||||
"vector": [-25, 0, 0]
|
"vector": [-37.5, 0, 0]
|
||||||
},
|
},
|
||||||
"1.0": {
|
"1.0": {
|
||||||
"vector": [-10, 0, 0]
|
"vector": [-10, 0, 0]
|
||||||
@ -58,7 +58,8 @@
|
|||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
},
|
},
|
||||||
"0.3333": {
|
"0.3333": {
|
||||||
"vector": [0, 2, 0]
|
"vector": [0, 2, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.6667": {
|
"0.6667": {
|
||||||
"vector": [-11, 3, 0],
|
"vector": [-11, 3, 0],
|
||||||
@ -72,7 +73,8 @@
|
|||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
},
|
},
|
||||||
"0.3333": {
|
"0.3333": {
|
||||||
"vector": [0, 2, 0]
|
"vector": [0, 2, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.6667": {
|
"0.6667": {
|
||||||
"vector": [11, 3, 0],
|
"vector": [11, 3, 0],
|
||||||
@ -108,6 +110,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sound_effects": {
|
||||||
|
"0.0": {
|
||||||
|
"effect": "buy_station"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"animation.model.idle": {
|
"animation.model.idle": {
|
||||||
@ -182,7 +189,7 @@
|
|||||||
"vector": [-10, 0, 0]
|
"vector": [-10, 0, 0]
|
||||||
},
|
},
|
||||||
"0.5833": {
|
"0.5833": {
|
||||||
"vector": [-25, 0, 0]
|
"vector": [-35, 0, 0]
|
||||||
},
|
},
|
||||||
"1.0": {
|
"1.0": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
@ -199,69 +206,86 @@
|
|||||||
"vector": [0, 6, -2]
|
"vector": [0, 6, -2]
|
||||||
},
|
},
|
||||||
"0.5833": {
|
"0.5833": {
|
||||||
"vector": [0, 6, -2]
|
"vector": [0, 6, -2],
|
||||||
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"1.0": {
|
"1.0": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0],
|
||||||
|
"easing": "linear"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"botshelfR": {
|
"botshelfR": {
|
||||||
"position": {
|
"position": {
|
||||||
"0.0": {
|
"0.25": {
|
||||||
"vector": [-11, 3, 0],
|
"vector": [-11, 3, 0],
|
||||||
"easing": "easeOutBack"
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.2917": {
|
|
||||||
"vector": [0, 2, 0]
|
|
||||||
},
|
|
||||||
"0.5417": {
|
"0.5417": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 2, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
|
},
|
||||||
|
"0.7917": {
|
||||||
|
"vector": [0, 0, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"botshelfL": {
|
"botshelfL": {
|
||||||
"position": {
|
"position": {
|
||||||
"0.0": {
|
"0.25": {
|
||||||
"vector": [11, 3, 0],
|
"vector": [11, 3, 0],
|
||||||
"easing": "easeOutBack"
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.2917": {
|
|
||||||
"vector": [0, 2, 0]
|
|
||||||
},
|
|
||||||
"0.5417": {
|
"0.5417": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 2, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
|
},
|
||||||
|
"0.7917": {
|
||||||
|
"vector": [0, 0, 0],
|
||||||
|
"easing": "easeOutBack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hingeL": {
|
"hingeL": {
|
||||||
"position": {
|
"position": {
|
||||||
"0.0": {
|
"0.25": {
|
||||||
"vector": [1, 3, 0],
|
"vector": [1, 3, 0],
|
||||||
"easing": "easeOutBack"
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.2917": {
|
"0.4167": {
|
||||||
|
"vector": [-1.57, 2.43, 0]
|
||||||
|
},
|
||||||
|
"0.5417": {
|
||||||
"vector": [0, 2, 0]
|
"vector": [0, 2, 0]
|
||||||
},
|
},
|
||||||
"0.5833": {
|
"0.8333": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hingeR": {
|
"hingeR": {
|
||||||
"position": {
|
"position": {
|
||||||
"0.0": {
|
"0.25": {
|
||||||
"vector": [-1, 3, 0],
|
"vector": [-1, 3, 0],
|
||||||
"easing": "easeOutBack"
|
"easing": "easeOutBack"
|
||||||
},
|
},
|
||||||
"0.2917": {
|
"0.4167": {
|
||||||
|
"vector": [1.57, 2.43, 0]
|
||||||
|
},
|
||||||
|
"0.5417": {
|
||||||
"vector": [0, 2, 0]
|
"vector": [0, 2, 0]
|
||||||
},
|
},
|
||||||
"0.5833": {
|
"0.8333": {
|
||||||
"vector": [0, 0, 0]
|
"vector": [0, 0, 0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sound_effects": {
|
||||||
|
"0.0": {
|
||||||
|
"effect": "buy_station"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "hardcore_redeploy:block/buy_station" }
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/hardcore_redeploy/icon.png
Normal file
BIN
src/main/resources/assets/hardcore_redeploy/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"block.hardcore_redeploy.buy_station": "Buy Station",
|
||||||
|
"effect.hardcore_redeploy.redeploying": "Redeploying",
|
||||||
|
"subtitles.hardcore_redeploy.buy_station": "Buy station noise"
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"credit": "Made with Blockbench",
|
||||||
|
"parent": "builtin/entity",
|
||||||
|
"texture_size": [
|
||||||
|
64,
|
||||||
|
64
|
||||||
|
],
|
||||||
|
"textures": {
|
||||||
|
"particle": "minecraft:block/hopper_outside"
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"thirdperson_righthand": {
|
||||||
|
"scale": [
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"thirdperson_lefthand": {
|
||||||
|
"scale": [
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"firstperson_righthand": {
|
||||||
|
"scale": [
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"firstperson_lefthand": {
|
||||||
|
"scale": [
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ground": {
|
||||||
|
"scale": [
|
||||||
|
0.7,
|
||||||
|
0.7,
|
||||||
|
0.7
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"gui": {
|
||||||
|
"rotation": [
|
||||||
|
0,
|
||||||
|
23,
|
||||||
|
21
|
||||||
|
],
|
||||||
|
"translation": [
|
||||||
|
1,
|
||||||
|
-2.75,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"scale": [
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fixed": {
|
||||||
|
"rotation": [
|
||||||
|
-90,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"parent": "hardcore_redeploy:block/buy_station"
|
||||||
|
}
|
8
src/main/resources/assets/hardcore_redeploy/sounds.json
Normal file
8
src/main/resources/assets/hardcore_redeploy/sounds.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"buy_station": {
|
||||||
|
"subtitle": "subtitles.hardcore_redeploy.buy_station",
|
||||||
|
"sounds": [
|
||||||
|
"hardcore_redeploy:buy_station"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 928 B |
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"type": "minecraft:block",
|
||||||
|
"pools": [
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "hardcore_redeploy:buy_station"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
"III",
|
||||||
|
"ICI",
|
||||||
|
"III"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"I": {
|
||||||
|
"item": "minecraft:iron_ingot"
|
||||||
|
},
|
||||||
|
"C": {
|
||||||
|
"item": "minecraft:crafting_table"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "hardcore_redeploy:buy_station",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"hardcore_redeploy:buy_station"
|
||||||
|
]
|
||||||
|
}
|
@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "hardcore-redeploy",
|
"id": "hardcore_redeploy",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
"name": "Hardcore Redeploy",
|
"name": "Hardcore Redeploy",
|
||||||
"description": "A mod that allows reviving players in hardcore servers, at a cost",
|
"description": "A mod that allows reviving players in hardcore servers, at a cost",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Hexugory",
|
"Hexugory",
|
||||||
"Kaptcha"
|
"Kaptchadelta"
|
||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
"sources": "https://git.touhoudiscord.net/Hexugory/HardcoreRedeploy"
|
"sources": "https://git.touhoudiscord.net/Hexugory/HardcoreRedeploy"
|
||||||
},
|
},
|
||||||
"license": "LGPL-3.0",
|
"license": "LGPL-3.0",
|
||||||
"icon": "assets/hardcore-redeploy/icon.png",
|
"icon": "assets/hardcore_redeploy/icon.png",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
@ -24,15 +24,19 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"hardcore-redeploy.mixins.json"
|
"hardcore_redeploy.mixins.json"
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.14.25",
|
"fabricloader": ">=0.14.25",
|
||||||
"minecraft": "~1.20.1",
|
"minecraft": "~1.20.1",
|
||||||
"java": ">=17",
|
"java": ">=17",
|
||||||
"fabric-api": "*"
|
"fabric-api": "*",
|
||||||
|
"geckolib": "^4.4.2"
|
||||||
},
|
},
|
||||||
"suggests": {
|
"custom": {
|
||||||
"another-mod": "*"
|
"loom:injected_interfaces": {
|
||||||
|
"net/minecraft/class_1657": ["net/touhoudiscord/BuyStationCapable"],
|
||||||
|
"net/minecraft/class_746": ["net/touhoudiscord/BuyStationCapable"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"required": true,
|
|
||||||
"package": "net.touhoudiscord.mixin",
|
|
||||||
"compatibilityLevel": "JAVA_17",
|
|
||||||
"mixins": [
|
|
||||||
"RedeployingMixin"
|
|
||||||
],
|
|
||||||
"injectors": {
|
|
||||||
"defaultRequire": 1
|
|
||||||
}
|
|
||||||
}
|
|
16
src/main/resources/hardcore_redeploy.mixins.json
Normal file
16
src/main/resources/hardcore_redeploy.mixins.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"package": "net.touhoudiscord.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_17",
|
||||||
|
"mixins": [
|
||||||
|
"BuyStationScreenMixin",
|
||||||
|
"RedeployingMixin",
|
||||||
|
"RedeployTimerMixin"
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
"ClientBuyStationScreenMixin"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user