Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Power-Ups #97

Draft
wants to merge 16 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/main/java/fr/hugman/mubble/Mubble.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
import com.google.common.reflect.Reflection;
import fr.hugman.mubble.block.MubbleBlockEntityTypes;
import fr.hugman.mubble.block.MubbleBlocks;
import fr.hugman.mubble.command.MubbleCommands;
import fr.hugman.mubble.entity.MubbleEntityTypes;
import fr.hugman.mubble.item.MubbleItemGroups;
import fr.hugman.mubble.item.MubbleItems;
import fr.hugman.mubble.item.consume.MubbleConsumeEffectTypes;
import fr.hugman.mubble.network.MubbleServerReceivers;
import fr.hugman.mubble.network.payload.MubblePayloads;
import fr.hugman.mubble.power_up.action.PowerUpActionTypes;
import fr.hugman.mubble.registry.MubbleRegistries;
import fr.hugman.mubble.screen.MubbleScreenHandlerTypes;
import fr.hugman.mubble.sound.MubbleSounds;
Expand All @@ -26,13 +31,20 @@ public void onInitialize() {
Reflection.initialize(MubbleItems.class);
Reflection.initialize(MubbleSounds.class);
Reflection.initialize(MubbleScreenHandlerTypes.class);
Reflection.initialize(MubbleConsumeEffectTypes.class);
MubbleEntityTypes.registerAttributes();

MubbleItemGroups.appendItemGroups();

MubbleGamerules.init();

Reflection.initialize(PowerUpActionTypes.class);

MubbleRegistries.register();

MubblePayloads.registerTypes();
MubbleServerReceivers.register();
MubbleCommands.register();
}

public static Identifier id(String path) {
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/fr/hugman/mubble/MubbleClient.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
package fr.hugman.mubble;

import com.google.common.reflect.Reflection;
import fr.hugman.mubble.block.MubbleBlocks;
import fr.hugman.mubble.client.gui.screen.BumpableScreen;
import fr.hugman.mubble.client.render.MubbleRenderLayers;
import fr.hugman.mubble.client.keybind.MubbleKeyBindings;
import fr.hugman.mubble.client.render.MubbleRenderers;
import fr.hugman.mubble.client.render.entity.model.MubbleModelLayers;
import fr.hugman.mubble.client.texture.MubbleSpriteManagers;
import fr.hugman.mubble.network.MubbleClientReceivers;
import fr.hugman.mubble.screen.MubbleScreenHandlerTypes;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.client.render.RenderLayer;

@Environment(EnvType.CLIENT)
public class MubbleClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
Reflection.initialize(MubbleModelLayers.class);
ClientLifecycleEvents.CLIENT_STOPPING.register(MubbleClient::onClientStop);

registerBlockRenderLayers();
registerHandledScreens();
MubbleRenderers.registerEntities();
MubbleRenderers.registerBlockEntities();
MubbleRenderLayers.registerLayers();
MubbleKeyBindings.registerEvents();
MubbleClientReceivers.register();
}

private static void registerBlockRenderLayers() {
Expand All @@ -31,4 +41,8 @@ private static void registerBlockRenderLayers() {
private static void registerHandledScreens() {
HandledScreens.register(MubbleScreenHandlerTypes.BUMPABLE_BLOCK, BumpableScreen::new);
}

private static void onClientStop(MinecraftClient client) {
MubbleSpriteManagers.stopSpriteManagers();
}
}
37 changes: 37 additions & 0 deletions src/main/java/fr/hugman/mubble/attribute/EntityAttributeEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package fr.hugman.mubble.attribute;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;

import java.util.List;
import java.util.Optional;

public record EntityAttributeEntry(RegistryEntry<EntityAttribute> attribute, EntityAttributeModifier modifier) {
public static final Codec<EntityAttributeEntry> CODEC = RecordCodecBuilder.create(instance -> instance.group(
EntityAttribute.CODEC.fieldOf("type").forGetter(EntityAttributeEntry::attribute),
EntityAttributeModifier.MAP_CODEC.forGetter(EntityAttributeEntry::modifier)
).apply(instance, EntityAttributeEntry::new)
);

public static final PacketCodec<RegistryByteBuf, EntityAttributeEntry> PACKET_CODEC = PacketCodec.tuple(
EntityAttribute.PACKET_CODEC,
EntityAttributeEntry::attribute,
EntityAttributeModifier.PACKET_CODEC,
EntityAttributeEntry::modifier,
EntityAttributeEntry::new
);

public static final PacketCodec<RegistryByteBuf, List<EntityAttributeEntry>> LIST_PACKET_CODEC = PACKET_CODEC.collect(PacketCodecs.toList());
public static final PacketCodec<RegistryByteBuf, Optional<List<EntityAttributeEntry>>> OPTIONAL_LIST_PACKET_CODEC = LIST_PACKET_CODEC.collect(PacketCodecs::optional);

public boolean matches(RegistryEntry<EntityAttribute> attribute, Identifier modifierId) {
return attribute.equals(this.attribute) && this.modifier.idMatches(modifierId);
}
}
16 changes: 16 additions & 0 deletions src/main/java/fr/hugman/mubble/block/MubbleBlockTags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fr.hugman.mubble.block;

import fr.hugman.mubble.Mubble;
import net.minecraft.block.Block;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey;

public class MubbleBlockTags {
public static final TagKey<Block> MELTABLE_TO_AIR = of("meltable/air");
public static final TagKey<Block> MELTABLE_TO_ICE = of("meltable/ice");
public static final TagKey<Block> MELTABLE_TO_WATER = of("meltable/water");

private static TagKey<Block> of(String path) {
return TagKey.of(RegistryKeys.BLOCK, Mubble.id(path));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package fr.hugman.mubble.client.gui.hud;

import fr.hugman.mubble.Mubble;
import fr.hugman.mubble.client.texture.PowerUpSpriteManager;
import fr.hugman.mubble.power_up.PowerUpHolder;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ColorHelper;

import java.util.Optional;

@Environment(EnvType.CLIENT)
public class PowerUpHudRendering {
private static final int OFFSET_FROM_SCREEN_BORDER = 1;
private static final int ITEM_TEXTURE_SIZE = 16; // should never EVER change...
private static final int BACKGROUND_TEXTURE_SIZE = 30;
private static final int ITEM_OFFSET = OFFSET_FROM_SCREEN_BORDER + (BACKGROUND_TEXTURE_SIZE - ITEM_TEXTURE_SIZE) / 2;
private static final Identifier EFFECT_BACKGROUND_TEXTURE = Mubble.id("hud/power_up_background");

public static void renderPowerUpLayer(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter) {
var powerUpOpt = Optional.ofNullable(client.player).flatMap(PowerUpHolder::getPowerUp);
if (powerUpOpt.isPresent()) {
context.drawGuiTexture(RenderLayer::getGuiTextured, EFFECT_BACKGROUND_TEXTURE, OFFSET_FROM_SCREEN_BORDER, OFFSET_FROM_SCREEN_BORDER, BACKGROUND_TEXTURE_SIZE, BACKGROUND_TEXTURE_SIZE);
Sprite sprite = PowerUpSpriteManager.INSTANCE.getSprite(powerUpOpt.get());
context.drawSpriteStretched(RenderLayer::getGuiTextured, sprite, ITEM_OFFSET, ITEM_OFFSET, ITEM_TEXTURE_SIZE, ITEM_TEXTURE_SIZE, ColorHelper.getWhite(1.0f));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fr.hugman.mubble.client.keybind;

import fr.hugman.mubble.client.power_up.PowerUpKeybindsHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;

@Environment(EnvType.CLIENT)
public class MubbleKeyBindings {
public static final KeyBinding TRIGGER_POWER_UP = of(GLFW.GLFW_KEY_R, "key.mubble.trigger_power_up", KeyBinding.GAMEPLAY_CATEGORY);

public static KeyBinding of(int code, String translationKey, String categoryTranslationKey) {
return KeyBindingHelper.registerKeyBinding(new KeyBinding(translationKey, InputUtil.Type.KEYSYM, code, categoryTranslationKey));
}

public static void registerEvents() {
ClientTickEvents.END_CLIENT_TICK.register(PowerUpKeybindsHandler::tick);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package fr.hugman.mubble.client.power_up;

import fr.hugman.mubble.client.keybind.MubbleKeyBindings;
import fr.hugman.mubble.network.payload.c2s.PowerUpTriggerPayload;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient;

public class PowerUpKeybindsHandler {
public static void tick(MinecraftClient client) {
if (null != client.player) {
var powerUpOpt = client.player.getPowerUp();
if (powerUpOpt.isPresent()) {
var powerUp = powerUpOpt.get().value();
// it's great to check the power-up allows certain actions on the client first
// to avoid unnecessary network traffic.
// let's utilize Minecraft's registry sync to my advantage
if(powerUp.canBeTriggered()) {
while(MubbleKeyBindings.TRIGGER_POWER_UP.wasPressed()) {
//TODO: check for cooldown
ClientPlayNetworking.send(PowerUpTriggerPayload.INSTANCE);
}
}
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.hugman.mubble.client.render;

import fr.hugman.mubble.block.MubbleBlockEntityTypes;
import fr.hugman.mubble.client.render.entity.FireballRenderer;
import fr.hugman.mubble.client.render.entity.GoombaRenderer;
import fr.hugman.mubble.entity.MubbleEntityTypes;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
Expand All @@ -9,6 +10,7 @@
public class MubbleRenderers {
public static void registerEntities() {
EntityRendererRegistry.register(MubbleEntityTypes.GOOMBA, GoombaRenderer::new);
EntityRendererRegistry.register(MubbleEntityTypes.FIREBALL, FireballRenderer::new);
}

public static void registerBlockEntities() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fr.hugman.mubble.client.render.entity;

import fr.hugman.mubble.client.render.entity.model.FireballEntityModel;
import fr.hugman.mubble.client.render.entity.model.MubbleModelLayers;
import fr.hugman.mubble.client.render.entity.state.FireballRenderState;
import fr.hugman.mubble.entity.FireballEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;

@Environment(EnvType.CLIENT)
public class FireballRenderer extends EntityRenderer<FireballEntity, FireballRenderState> {
private static final Identifier TEXTURE = Identifier.ofVanilla("textures/block/orange_concrete.png");
private static final RenderLayer LAYER = RenderLayer.getEntityTranslucent(TEXTURE);

private final FireballEntityModel model;
private final float MIN_SQUISH = 0.45f;
private final float MAX_SQUISH = 2.0f;
private final float SPEED_SQUISH_SCALE = 0.5f;

public FireballRenderer(EntityRendererFactory.Context ctx) {
super(ctx);
this.model = new FireballEntityModel(ctx.getPart(MubbleModelLayers.FIREBALL));
}

@Override
public FireballRenderState createRenderState() {
return new FireballRenderState();
}

@Override
public void render(FireballRenderState state, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
matrices.push();

matrices.translate(0.0D, state.height / 2.0D, 0.0D);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(state.yaw - 90.0F));
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(state.pitch));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(MathHelper.sin(state.age * 0.15F) * 360.0F));

var newScale = (state.width * 2) / (FireballEntityModel.SIZE / 16) - MAX_SQUISH * 2;
matrices.scale(newScale, newScale, newScale);

float squish = (float) Math.max(Math.min(1 - state.speed * SPEED_SQUISH_SCALE, MAX_SQUISH), MIN_SQUISH);
matrices.scale(1 / squish, squish, squish);

this.model.setAngles(state);
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(this.model.getLayer(TEXTURE));
this.model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV);

matrices.pop();

super.render(state, matrices, vertexConsumers, light);
}

@Override
public void updateRenderState(FireballEntity bullet, FireballRenderState state, float f) {
super.updateRenderState(bullet, state, f);
state.pitch = bullet.getLerpedPitch(f);
state.yaw = bullet.getLerpedYaw(f);
state.speed = bullet.getSpeed();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fr.hugman.mubble.client.render.entity;

import fr.hugman.mubble.client.render.MubbleRenderLayers;
import fr.hugman.mubble.client.render.entity.model.GoombaModel;
import fr.hugman.mubble.client.render.entity.model.MubbleModelLayers;
import fr.hugman.mubble.client.render.entity.state.GoombaEntityRenderState;
import fr.hugman.mubble.entity.GoombaEntity;
import net.fabricmc.api.EnvType;
Expand All @@ -14,7 +14,7 @@
@Environment(EnvType.CLIENT)
public class GoombaRenderer extends MobEntityRenderer<GoombaEntity, GoombaEntityRenderState, GoombaModel> {
public GoombaRenderer(EntityRendererFactory.Context context) {
super(context, new GoombaModel(context.getPart(MubbleRenderLayers.GOOMBA)), 0.4f);
super(context, new GoombaModel(context.getPart(MubbleModelLayers.GOOMBA)), 0.4f);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package fr.hugman.mubble.client.render.entity.model;

import fr.hugman.mubble.client.render.entity.state.FireballRenderState;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.model.*;
import net.minecraft.client.render.entity.model.EntityModel;

@Environment(EnvType.CLIENT)
public class FireballEntityModel extends EntityModel<FireballRenderState> {
public static final String MAIN = "main";
public static final float SIZE = 1;

public FireballEntityModel(ModelPart root) {
super(root);
}

public static TexturedModelData getTexturedModelData() {
ModelData modelData = new ModelData();
ModelPartData modelPartData = modelData.getRoot();
modelPartData.addChild(
MAIN,
ModelPartBuilder.create()
.uv(0, 0)
.cuboid(-SIZE / 2, -SIZE / 2, -SIZE / 2, SIZE, SIZE, SIZE),
ModelTransform.pivot(0F, 0F, 0F)
);
return TexturedModelData.of(modelData, 16, 16);
}
}
Loading