add the mod
This commit is contained in:
parent
300d509baa
commit
871c10bba3
@ -11,7 +11,7 @@ loader_version=0.14.25
|
||||
# Mod Properties
|
||||
mod_version=1.0.0
|
||||
maven_group=net.touhoudiscord
|
||||
archives_base_name=hardcore-redeploy
|
||||
archives_base_name=hardcore_redeploy
|
||||
|
||||
# Dependencies
|
||||
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;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
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.entity.FabricBlockEntityTypeBuilder;
|
||||
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.entity.effect.StatusEffect;
|
||||
import net.minecraft.entity.projectile.FireworkRocketEntity;
|
||||
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.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.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.BuyStationEntity;
|
||||
import net.touhoudiscord.commands.RedeployPlayerCommand;
|
||||
@ -23,26 +37,104 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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 static final String MOD_ID = "hardcore-redeploy";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("hardcore-redeploy");
|
||||
public static final String MOD_ID = "hardcore_redeploy";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("hardcore_redeploy");
|
||||
|
||||
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 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 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
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Initializing Hardcore Redeploy");
|
||||
|
||||
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,
|
||||
new Identifier(HardcoreRedeploy.MOD_ID, "buy_station_entity"),
|
||||
FabricBlockEntityTypeBuilder.create(BuyStationEntity::new,
|
||||
HardcoreRedeploy.BUY_STATION).build());
|
||||
Registry.register(Registries.STATUS_EFFECT, new Identifier(HardcoreRedeploy.MOD_ID, "redeploying"), REDEPLOYING);
|
||||
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;
|
||||
|
||||
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.touhoudiscord.HardcoreRedeployConfigHandler.HardcoreRedeployConfig;
|
||||
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 static HashMap<UUID, Integer> reviveMap = new HashMap<>();
|
||||
public static HardcoreRedeployConfig serverConfig = HardcoreRedeployConfigHandler.config;
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
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 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));
|
||||
spectator.teleport(target.getServerWorld(), target.getPos().x, target.getServerWorld().getDimension().hasCeiling() ? target.getPos().y : 320, target.getPos().z, 0, 30);
|
||||
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;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.BlockWithEntity;
|
||||
import net.minecraft.block.*;
|
||||
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.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.touhoudiscord.BuyStationCapable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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) {
|
||||
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
|
||||
@Override
|
||||
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
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.MODEL;
|
||||
return state.get(BUY_STATION_PART) == BuyStationPart.MAIN ? BlockRenderType.MODEL : BlockRenderType.INVISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
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.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.touhoudiscord.HardcoreRedeploy;
|
||||
import software.bernie.geckolib.animatable.GeoBlockEntity;
|
||||
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
||||
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;
|
||||
|
||||
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 CLOSE = RawAnimation.begin().thenPlay("animation.model.close");
|
||||
@ -26,11 +30,20 @@ public class BuyStationEntity extends BlockEntity implements GeoBlockEntity {
|
||||
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
||||
controllers.add(new AnimationController<>(this, "buystationcontroller", 0, state -> {
|
||||
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);
|
||||
else
|
||||
}
|
||||
else {
|
||||
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
|
||||
|
@ -1,10 +1,13 @@
|
||||
package net.touhoudiscord.block.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.touhoudiscord.HardcoreRedeploy;
|
||||
import net.touhoudiscord.block.BuyStationEntity;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BuyStationModel extends GeoModel<BuyStationEntity> {
|
||||
@Override
|
||||
public Identifier getModelResource(BuyStationEntity animatable) {
|
||||
|
@ -1,11 +1,27 @@
|
||||
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.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.touhoudiscord.block.BuyStationEntity;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoBlockRenderer;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BuyStationRenderer extends GeoBlockRenderer<BuyStationEntity> {
|
||||
public BuyStationRenderer(BlockEntityRendererFactory.Context context) {
|
||||
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.text.Text;
|
||||
import net.minecraft.world.GameMode;
|
||||
import net.touhoudiscord.HardcoreRedeploy;
|
||||
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 {
|
||||
|
||||
@ -36,7 +36,5 @@ public class RedeployPlayerCommand {
|
||||
|
||||
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.core.animatable.instance.AnimatableInstanceCache;
|
||||
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.util.RenderUtils;
|
||||
|
||||
@ -17,7 +18,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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);
|
||||
|
||||
public BuyStationItem(Block block, Settings settings) {
|
||||
|
@ -1,10 +1,13 @@
|
||||
package net.touhoudiscord.item.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.touhoudiscord.HardcoreRedeploy;
|
||||
import net.touhoudiscord.item.BuyStationItem;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BuyStationItemModel extends GeoModel<BuyStationItem> {
|
||||
@Override
|
||||
public Identifier getModelResource(BuyStationItem animatable) {
|
||||
|
@ -1,8 +1,11 @@
|
||||
package net.touhoudiscord.item.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.touhoudiscord.item.BuyStationItem;
|
||||
import software.bernie.geckolib.renderer.GeoItemRenderer;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BuyStationItemRenderer extends GeoItemRenderer<BuyStationItem> {
|
||||
public BuyStationItemRenderer() {
|
||||
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]
|
||||
},
|
||||
"0.25": {
|
||||
"vector": [-25, 0, 0]
|
||||
"vector": [-37.5, 0, 0]
|
||||
},
|
||||
"1.0": {
|
||||
"vector": [-10, 0, 0]
|
||||
@ -58,7 +58,8 @@
|
||||
"vector": [0, 0, 0]
|
||||
},
|
||||
"0.3333": {
|
||||
"vector": [0, 2, 0]
|
||||
"vector": [0, 2, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.6667": {
|
||||
"vector": [-11, 3, 0],
|
||||
@ -72,7 +73,8 @@
|
||||
"vector": [0, 0, 0]
|
||||
},
|
||||
"0.3333": {
|
||||
"vector": [0, 2, 0]
|
||||
"vector": [0, 2, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.6667": {
|
||||
"vector": [11, 3, 0],
|
||||
@ -108,6 +110,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.0": {
|
||||
"effect": "buy_station"
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.model.idle": {
|
||||
@ -182,7 +189,7 @@
|
||||
"vector": [-10, 0, 0]
|
||||
},
|
||||
"0.5833": {
|
||||
"vector": [-25, 0, 0]
|
||||
"vector": [-35, 0, 0]
|
||||
},
|
||||
"1.0": {
|
||||
"vector": [0, 0, 0]
|
||||
@ -199,69 +206,86 @@
|
||||
"vector": [0, 6, -2]
|
||||
},
|
||||
"0.5833": {
|
||||
"vector": [0, 6, -2]
|
||||
"vector": [0, 6, -2],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"1.0": {
|
||||
"vector": [0, 0, 0]
|
||||
"vector": [0, 0, 0],
|
||||
"easing": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
"botshelfR": {
|
||||
"position": {
|
||||
"0.0": {
|
||||
"0.25": {
|
||||
"vector": [-11, 3, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.2917": {
|
||||
"vector": [0, 2, 0]
|
||||
},
|
||||
"0.5417": {
|
||||
"vector": [0, 0, 0]
|
||||
"vector": [0, 2, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.7917": {
|
||||
"vector": [0, 0, 0],
|
||||
"easing": "easeOutBack"
|
||||
}
|
||||
}
|
||||
},
|
||||
"botshelfL": {
|
||||
"position": {
|
||||
"0.0": {
|
||||
"0.25": {
|
||||
"vector": [11, 3, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.2917": {
|
||||
"vector": [0, 2, 0]
|
||||
},
|
||||
"0.5417": {
|
||||
"vector": [0, 0, 0]
|
||||
"vector": [0, 2, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.7917": {
|
||||
"vector": [0, 0, 0],
|
||||
"easing": "easeOutBack"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hingeL": {
|
||||
"position": {
|
||||
"0.0": {
|
||||
"0.25": {
|
||||
"vector": [1, 3, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.2917": {
|
||||
"0.4167": {
|
||||
"vector": [-1.57, 2.43, 0]
|
||||
},
|
||||
"0.5417": {
|
||||
"vector": [0, 2, 0]
|
||||
},
|
||||
"0.5833": {
|
||||
"0.8333": {
|
||||
"vector": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"hingeR": {
|
||||
"position": {
|
||||
"0.0": {
|
||||
"0.25": {
|
||||
"vector": [-1, 3, 0],
|
||||
"easing": "easeOutBack"
|
||||
},
|
||||
"0.2917": {
|
||||
"0.4167": {
|
||||
"vector": [1.57, 2.43, 0]
|
||||
},
|
||||
"0.5417": {
|
||||
"vector": [0, 2, 0]
|
||||
},
|
||||
"0.5833": {
|
||||
"0.8333": {
|
||||
"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,
|
||||
"id": "hardcore-redeploy",
|
||||
"id": "hardcore_redeploy",
|
||||
"version": "${version}",
|
||||
"name": "Hardcore Redeploy",
|
||||
"description": "A mod that allows reviving players in hardcore servers, at a cost",
|
||||
"authors": [
|
||||
"Hexugory",
|
||||
"Kaptcha"
|
||||
"Kaptchadelta"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "",
|
||||
"sources": "https://git.touhoudiscord.net/Hexugory/HardcoreRedeploy"
|
||||
},
|
||||
"license": "LGPL-3.0",
|
||||
"icon": "assets/hardcore-redeploy/icon.png",
|
||||
"icon": "assets/hardcore_redeploy/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
@ -24,15 +24,19 @@
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"hardcore-redeploy.mixins.json"
|
||||
"hardcore_redeploy.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.25",
|
||||
"minecraft": "~1.20.1",
|
||||
"java": ">=17",
|
||||
"fabric-api": "*"
|
||||
"fabric-api": "*",
|
||||
"geckolib": "^4.4.2"
|
||||
},
|
||||
"suggests": {
|
||||
"another-mod": "*"
|
||||
"custom": {
|
||||
"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