mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
Fwoomp of Duty: Black Crops 4
- Introduced proper first-person rendering of Potato Cannons, inherited from blockzappers - Introduced proper dual wield handling for Potato Cannons - Potato cannons are no longer stackable - Added a couple more attributes to ammo types - potatoes and carrots now plant a crop when hitting farmland - Added a couple particle effects - Fwoomp sound now slightly randomizes its pitch
This commit is contained in:
parent
6feacd3fc2
commit
fbcaa1b931
16 changed files with 670 additions and 329 deletions
|
@ -60,8 +60,8 @@ public class Create {
|
|||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static final Gson GSON = new GsonBuilder().setPrettyPrinting()
|
||||
.disableHtmlEscaping()
|
||||
.create();
|
||||
.disableHtmlEscaping()
|
||||
.create();
|
||||
|
||||
public static final ItemGroup BASE_CREATIVE_TAB = new CreateItemGroup();
|
||||
public static final ItemGroup PALETTES_CREATIVE_TAB = new PalettesItemGroup();
|
||||
|
@ -90,7 +90,7 @@ public class Create {
|
|||
AllConfigs.register();
|
||||
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||
.getModEventBus();
|
||||
.getModEventBus();
|
||||
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
|
||||
|
||||
modEventBus.addListener(Create::init);
|
||||
|
@ -104,7 +104,8 @@ public class Create {
|
|||
modEventBus.addListener(EventPriority.LOWEST, this::gatherData);
|
||||
forgeEventBus.addListener(EventPriority.HIGH, Create::onBiomeLoad);
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.addClientListeners(modEventBus));
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> CreateClient.addClientListeners(forgeEventBus, modEventBus));
|
||||
}
|
||||
|
||||
public static void init(final FMLCommonSetupEvent event) {
|
||||
|
|
|
@ -10,6 +10,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
|
||||
import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer;
|
||||
import com.simibubi.create.content.curiosities.weapons.PotatoCannonRenderHandler;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler;
|
||||
import com.simibubi.create.content.schematics.ClientSchematicLoader;
|
||||
import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler;
|
||||
import com.simibubi.create.content.schematics.client.SchematicHandler;
|
||||
|
@ -63,12 +65,15 @@ public class CreateClient {
|
|||
public static final Outliner OUTLINER = new Outliner();
|
||||
public static final GhostBlocks GHOST_BLOCKS = new GhostBlocks();
|
||||
|
||||
public static final ZapperRenderHandler ZAPPER_RENDER_HANDLER = new ZapperRenderHandler();
|
||||
public static final PotatoCannonRenderHandler POTATO_CANNON_RENDER_HANDLER = new PotatoCannonRenderHandler();
|
||||
|
||||
private static CustomBlockModels customBlockModels;
|
||||
private static CustomItemModels customItemModels;
|
||||
private static CustomRenderedItems customRenderedItems;
|
||||
private static CasingConnectivity casingConnectivity;
|
||||
|
||||
public static void addClientListeners(IEventBus modEventBus) {
|
||||
public static void addClientListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
modEventBus.addListener(CreateClient::clientInit);
|
||||
modEventBus.addListener(CreateClient::onTextureStitch);
|
||||
modEventBus.addListener(CreateClient::onModelRegistry);
|
||||
|
@ -78,6 +83,9 @@ public class CreateClient {
|
|||
modEventBus.addListener(CreateContexts::flwInit);
|
||||
modEventBus.addListener(AllMaterialSpecs::flwInit);
|
||||
modEventBus.addListener(ContraptionRenderDispatcher::invalidateOnGatherContext);
|
||||
|
||||
ZAPPER_RENDER_HANDLER.register(forgeEventBus);
|
||||
POTATO_CANNON_RENDER_HANDLER.register(forgeEventBus);
|
||||
}
|
||||
|
||||
public static void clientInit(FMLClientSetupEvent event) {
|
||||
|
@ -96,7 +104,7 @@ public class CreateClient {
|
|||
UIRenderHelper.init();
|
||||
|
||||
IResourceManager resourceManager = Minecraft.getInstance()
|
||||
.getResourceManager();
|
||||
.getResourceManager();
|
||||
if (resourceManager instanceof IReloadableResourceManager)
|
||||
((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler());
|
||||
|
||||
|
@ -107,19 +115,19 @@ public class CreateClient {
|
|||
|
||||
public static void onTextureStitch(TextureStitchEvent.Pre event) {
|
||||
if (!event.getMap()
|
||||
.getId()
|
||||
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE))
|
||||
.getId()
|
||||
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE))
|
||||
return;
|
||||
SpriteShifter.getAllTargetSprites()
|
||||
.forEach(event::addSprite);
|
||||
.forEach(event::addSprite);
|
||||
}
|
||||
|
||||
public static void onModelRegistry(ModelRegistryEvent event) {
|
||||
PartialModel.onModelRegistry(event);
|
||||
|
||||
getCustomRenderedItems().foreach((item, modelFunc) -> modelFunc.apply(null)
|
||||
.getModelLocations()
|
||||
.forEach(ModelLoader::addSpecialModel));
|
||||
.getModelLocations()
|
||||
.forEach(ModelLoader::addSpecialModel));
|
||||
}
|
||||
|
||||
public static void onModelBake(ModelBakeEvent event) {
|
||||
|
@ -127,9 +135,9 @@ public class CreateClient {
|
|||
PartialModel.onModelBake(event);
|
||||
|
||||
getCustomBlockModels()
|
||||
.foreach((block, modelFunc) -> swapModels(modelRegistry, getAllBlockStateModelLocations(block), modelFunc));
|
||||
.foreach((block, modelFunc) -> swapModels(modelRegistry, getAllBlockStateModelLocations(block), modelFunc));
|
||||
getCustomItemModels()
|
||||
.foreach((item, modelFunc) -> swapModels(modelRegistry, getItemModelLocation(item), modelFunc));
|
||||
.foreach((item, modelFunc) -> swapModels(modelRegistry, getItemModelLocation(item), modelFunc));
|
||||
getCustomRenderedItems().foreach((item, modelFunc) -> {
|
||||
swapModels(modelRegistry, getItemModelLocation(item), m -> modelFunc.apply(m)
|
||||
.loadPartials(event));
|
||||
|
|
|
@ -5,9 +5,11 @@ import java.util.Optional;
|
|||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.curiosities.armor.BackTankUtil;
|
||||
import com.simibubi.create.content.curiosities.zapper.ShootableGadgetItemMethods;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
|
@ -15,16 +17,15 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.item.ShootableItem;
|
||||
import net.minecraft.item.UseAction;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
@ -34,14 +35,13 @@ import net.minecraft.util.text.TranslationTextComponent;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class PotatoCannonItem extends ShootableItem {
|
||||
|
||||
public static ItemStack CLIENT_CURRENT_AMMO = ItemStack.EMPTY;
|
||||
public static final int MAX_DAMAGE = 100;
|
||||
|
||||
public static int PREV_SHOT = 0;
|
||||
public static int PREV_SHOT = 0;// remove this
|
||||
|
||||
public PotatoCannonItem(Properties p_i48487_1_) {
|
||||
super(p_i48487_1_);
|
||||
|
@ -58,6 +58,11 @@ public class PotatoCannonItem extends ShootableItem {
|
|||
return onItemRightClick(context.getWorld(), context.getPlayer(), context.getHand()).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemStackLimit(ItemStack stack) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRGBDurabilityForDisplay(ItemStack stack) {
|
||||
return BackTankUtil.getRGBDurabilityForDisplay(stack, maxUses());
|
||||
|
@ -82,6 +87,10 @@ public class PotatoCannonItem extends ShootableItem {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean isCannon(ItemStack stack) {
|
||||
return stack.getItem() instanceof PotatoCannonItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxDamage(ItemStack stack) {
|
||||
return MAX_DAMAGE;
|
||||
|
@ -90,32 +99,41 @@ public class PotatoCannonItem extends ShootableItem {
|
|||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
if (world.isRemote)
|
||||
return ActionResult.pass(stack);
|
||||
return findAmmoInInventory(world, player, stack).map(itemStack -> {
|
||||
|
||||
findAmmoInInventory(world, player, stack).ifPresent(itemStack -> {
|
||||
PotatoProjectileEntity projectile = AllEntityTypes.POTATO_PROJECTILE.create(world);
|
||||
Vector3d offset = VecHelper.rotate(player.getLookVec()
|
||||
.scale(1.25f), (hand == Hand.MAIN_HAND) == (player.getPrimaryHand() == HandSide.RIGHT) ? -25 : 25,
|
||||
Axis.Y);
|
||||
Vector3d vec = player.getBoundingBox()
|
||||
.getCenter()
|
||||
.add(0, player.getBoundingBox()
|
||||
.getYSize() / 5f, 0)
|
||||
.add(offset);
|
||||
if (ShootableGadgetItemMethods.shouldSwap(player, stack, hand, this::isCannon))
|
||||
return ActionResult.fail(stack);
|
||||
|
||||
projectile.setPosition(vec.x, vec.y, vec.z);
|
||||
projectile.setMotion(player.getLookVec()
|
||||
.scale(1.75f));
|
||||
projectile.setItem(itemStack);
|
||||
projectile.setShooter(player);
|
||||
world.addEntity(projectile);
|
||||
PotatoProjectileEntity.playLaunchSound(world, player.getPositionVec(), projectile.getProjectileType()
|
||||
.getSoundPitch());
|
||||
if (world.isRemote) {
|
||||
CreateClient.POTATO_CANNON_RENDER_HANDLER.dontAnimateItem(hand);
|
||||
return ActionResult.success(stack);
|
||||
}
|
||||
|
||||
Vector3d barrelPos = ShootableGadgetItemMethods.getGunBarrelVec(player, hand == Hand.MAIN_HAND,
|
||||
new Vector3d(.75f, -0.3f, 1.5f));
|
||||
Vector3d correction =
|
||||
ShootableGadgetItemMethods.getGunBarrelVec(player, hand == Hand.MAIN_HAND, new Vector3d(-.05f, 0, 0))
|
||||
.subtract(player.getPositionVec()
|
||||
.add(0, player.getEyeHeight(), 0));
|
||||
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player),
|
||||
new PotatoCannonPacket());
|
||||
Vector3d lookVec = player.getLookVec();
|
||||
|
||||
PotatoCannonProjectileTypes projectileType = PotatoCannonProjectileTypes.getProjectileTypeOf(itemStack)
|
||||
.orElse(PotatoCannonProjectileTypes.FALLBACK);
|
||||
float soundPitch = projectileType.getSoundPitch() + (Create.RANDOM.nextFloat() - .5f) / 4f;
|
||||
boolean spray = projectileType.getSplit() > 1;
|
||||
for (int i = 0; i < projectileType.getSplit(); i++) {
|
||||
PotatoProjectileEntity projectile = AllEntityTypes.POTATO_PROJECTILE.create(world);
|
||||
projectile.setItem(itemStack);
|
||||
Vector3d motion = lookVec.scale(projectileType.getVelocityMultiplier())
|
||||
.add(correction);
|
||||
if (spray)
|
||||
motion = VecHelper.offsetRandomly(motion, Create.RANDOM, 0.25f);
|
||||
projectile.setPosition(barrelPos.x, barrelPos.y, barrelPos.z);
|
||||
projectile.setMotion(motion);
|
||||
projectile.setShooter(player);
|
||||
world.addEntity(projectile);
|
||||
}
|
||||
|
||||
if (!player.isCreative()) {
|
||||
itemStack.shrink(1);
|
||||
|
@ -130,11 +148,13 @@ public class PotatoCannonItem extends ShootableItem {
|
|||
findAmmoInInventory(world, player, stack).flatMap(PotatoCannonProjectileTypes::getProjectileTypeOf)
|
||||
.map(PotatoCannonProjectileTypes::getReloadTicks)
|
||||
.orElse(10);
|
||||
player.getCooldownTracker()
|
||||
.setCooldown(this, cooldown);
|
||||
});
|
||||
|
||||
return ActionResult.pass(stack);
|
||||
ShootableGadgetItemMethods.applyCooldown(player, stack, hand, this::isCannon, cooldown);
|
||||
ShootableGadgetItemMethods.sendPackets(player,
|
||||
b -> new PotatoCannonPacket(barrelPos, lookVec.normalize(), itemStack, hand, soundPitch, b));
|
||||
return ActionResult.success(stack);
|
||||
})
|
||||
.orElse(ActionResult.pass(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,6 +212,21 @@ public class PotatoCannonItem extends ShootableItem {
|
|||
.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemEnchantability() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEntitySwing(ItemStack stack, LivingEntity entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UseAction getUseAction(ItemStack stack) {
|
||||
return UseAction.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRange() {
|
||||
return 15;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.curiosities.weapons;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
|
||||
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
@ -13,6 +14,8 @@ import net.minecraft.client.renderer.ItemRenderer;
|
|||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
|
||||
public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer<PotatoCannonModel> {
|
||||
|
@ -26,16 +29,18 @@ public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer<Po
|
|||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
boolean mainHand = player.getHeldItemMainhand() == stack;
|
||||
boolean offHand = player.getHeldItemOffhand() == stack;
|
||||
boolean leftHanded = player.getPrimaryHand() == HandSide.LEFT;
|
||||
|
||||
float speed = PotatoCannonItem.PREV_SHOT == 0 ? 0
|
||||
: (PotatoCannonItem.PREV_SHOT - AnimationTickHolder.getPartialTicks()) / 5f;
|
||||
float offset = .5f / 16;
|
||||
float worldTime = AnimationTickHolder.getRenderTime() / 10;
|
||||
float angle = worldTime * -25;
|
||||
if (mainHand || offHand)
|
||||
angle += 30 * speed * speed;
|
||||
float speed = CreateClient.POTATO_CANNON_RENDER_HANDLER.getAnimation(mainHand ^ leftHanded,
|
||||
AnimationTickHolder.getPartialTicks());
|
||||
|
||||
if (mainHand || offHand)
|
||||
angle += 360 * MathHelper.clamp(speed * 5, 0, 1);
|
||||
angle %= 360;
|
||||
float offset = .5f / 16;
|
||||
|
||||
ms.push();
|
||||
ms.translate(0, offset, 0);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle));
|
||||
|
|
|
@ -1,27 +1,59 @@
|
|||
package com.simibubi.create.content.curiosities.weapons;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.curiosities.zapper.ShootGadgetPacket;
|
||||
import com.simibubi.create.content.curiosities.zapper.ShootableGadgetRenderHandler;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class PotatoCannonPacket extends SimplePacketBase {
|
||||
public class PotatoCannonPacket extends ShootGadgetPacket {
|
||||
|
||||
public PotatoCannonPacket() {}
|
||||
private float pitch;
|
||||
private Vector3d motion;
|
||||
private ItemStack item;
|
||||
|
||||
public PotatoCannonPacket(PacketBuffer buffer) {}
|
||||
public PotatoCannonPacket(Vector3d location, Vector3d motion, ItemStack item, Hand hand, float pitch, boolean self) {
|
||||
super(location, hand, self);
|
||||
this.motion = motion;
|
||||
this.item = item;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public PotatoCannonPacket(PacketBuffer buffer) {
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {}
|
||||
protected void readAdditional(PacketBuffer buffer) {
|
||||
pitch = buffer.readFloat();
|
||||
motion = new Vector3d(buffer.readFloat(), buffer.readFloat(), buffer.readFloat());
|
||||
item = buffer.readItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> PotatoCannonItem.PREV_SHOT = 15);
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
protected void writeAdditional(PacketBuffer buffer) {
|
||||
buffer.writeFloat(pitch);
|
||||
buffer.writeFloat((float) motion.x);
|
||||
buffer.writeFloat((float) motion.y);
|
||||
buffer.writeFloat((float) motion.z);
|
||||
buffer.writeItemStack(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected void handleAdditional() {
|
||||
CreateClient.POTATO_CANNON_RENDER_HANDLER.beforeShoot(pitch, location, motion, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected ShootableGadgetRenderHandler getHandler() {
|
||||
return CreateClient.POTATO_CANNON_RENDER_HANDLER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,21 +3,30 @@ package com.simibubi.create.content.curiosities.weapons;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.IItemProvider;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.EntityRayTraceResult;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
import net.minecraftforge.registries.IRegistryDelegate;
|
||||
|
||||
public class PotatoCannonProjectileTypes {
|
||||
|
@ -31,13 +40,16 @@ public class PotatoCannonProjectileTypes {
|
|||
|
||||
POTATO = create("potato").damage(4)
|
||||
.reloadTicks(15)
|
||||
.velocity(1.25f)
|
||||
.knockback(1.5f)
|
||||
.renderTumbling()
|
||||
.onBlockHit(plantCrop(Blocks.POTATOES.delegate))
|
||||
.registerAndAssign(Items.POTATO),
|
||||
|
||||
BAKED_POTATO = create("baked_potato").damage(3)
|
||||
.reloadTicks(15)
|
||||
.knockback(1.5f)
|
||||
.velocity(1.05f)
|
||||
.knockback(0.5f)
|
||||
.renderTumbling()
|
||||
.onEntityHit(ray -> ray.getEntity()
|
||||
.setFireTicks(10))
|
||||
|
@ -45,28 +57,35 @@ public class PotatoCannonProjectileTypes {
|
|||
|
||||
CARROT = create("carrot").damage(3)
|
||||
.renderTowardMotion(140, 1)
|
||||
.velocity(1.25f)
|
||||
.velocity(1.45f)
|
||||
.knockback(0.5f)
|
||||
.soundPitch(1.25f)
|
||||
.onBlockHit(plantCrop(Blocks.CARROTS.delegate))
|
||||
.registerAndAssign(Items.CARROT),
|
||||
|
||||
GOLDEN_CARROT = create("golden_carrot").damage(8)
|
||||
.reloadTicks(20)
|
||||
.knockback(0.5f)
|
||||
.velocity(1.25f)
|
||||
.velocity(1.45f)
|
||||
.renderTowardMotion(140, 2)
|
||||
.soundPitch(1.25f)
|
||||
.registerAndAssign(Items.GOLDEN_CARROT),
|
||||
|
||||
SWEET_BERRIES = create("sweet_berry").damage(1)
|
||||
.reloadTicks(10)
|
||||
.knockback(0.1f)
|
||||
.velocity(1.05f)
|
||||
.renderTumbling()
|
||||
.splitInto(3)
|
||||
.soundPitch(1.25f)
|
||||
.registerAndAssign(Items.SWEET_BERRIES),
|
||||
|
||||
POISON_POTATO = create("poison_potato").damage(5)
|
||||
.reloadTicks(15)
|
||||
.knockback(0.5f)
|
||||
.knockback(0.05f)
|
||||
.velocity(1.25f)
|
||||
.renderTumbling()
|
||||
.onEntityHit(ray -> {
|
||||
Entity entity = ray.getEntity();
|
||||
if (entity instanceof LivingEntity)
|
||||
((LivingEntity) entity).addPotionEffect(new EffectInstance(Effects.POISON, 40));
|
||||
})
|
||||
.onEntityHit(potion(Effects.POISON, 4))
|
||||
.registerAndAssign(Items.POISONOUS_POTATO)
|
||||
|
||||
;
|
||||
|
@ -93,20 +112,30 @@ public class PotatoCannonProjectileTypes {
|
|||
|
||||
private float gravityMultiplier = 1;
|
||||
private float velocityMultiplier = 1;
|
||||
private float drag = 0.99f;
|
||||
private float knockback = 1;
|
||||
private int reloadTicks = 10;
|
||||
private int damage = 1;
|
||||
private int split = 1;
|
||||
private float fwoompPitch = 1;
|
||||
private PotatoProjectileRenderMode renderMode = new PotatoProjectileRenderMode.Billboard();
|
||||
private Consumer<EntityRayTraceResult> onEntityHit = e -> {
|
||||
};
|
||||
private Consumer<BlockRayTraceResult> onBlockHit = e -> {
|
||||
private BiConsumer<IWorld, BlockRayTraceResult> onBlockHit = (w, ray) -> {
|
||||
};
|
||||
|
||||
public float getGravityMultiplier() {
|
||||
return gravityMultiplier;
|
||||
}
|
||||
|
||||
public float getDrag() {
|
||||
return drag;
|
||||
}
|
||||
|
||||
public int getSplit() {
|
||||
return split;
|
||||
}
|
||||
|
||||
public float getVelocityMultiplier() {
|
||||
return velocityMultiplier;
|
||||
}
|
||||
|
@ -135,8 +164,35 @@ public class PotatoCannonProjectileTypes {
|
|||
onEntityHit.accept(ray);
|
||||
}
|
||||
|
||||
public void onBlockHit(BlockRayTraceResult ray) {
|
||||
onBlockHit.accept(ray);
|
||||
public void onBlockHit(IWorld world, BlockRayTraceResult ray) {
|
||||
onBlockHit.accept(world, ray);
|
||||
}
|
||||
|
||||
private static Consumer<EntityRayTraceResult> potion(Effect effect, int seconds) {
|
||||
return ray -> {
|
||||
Entity entity = ray.getEntity();
|
||||
if (entity instanceof LivingEntity)
|
||||
((LivingEntity) entity).addPotionEffect(new EffectInstance(Effects.POISON, 80));
|
||||
};
|
||||
}
|
||||
|
||||
private static BiConsumer<IWorld, BlockRayTraceResult> plantCrop(IRegistryDelegate<? extends Block> cropBlock) {
|
||||
return (world, ray) -> {
|
||||
BlockPos pos = ray.getPos();
|
||||
if (!world.isAreaLoaded(pos, 1))
|
||||
return;
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (!world.getBlockState(pos.up())
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
return;
|
||||
if (!(cropBlock.get() instanceof IPlantable))
|
||||
return;
|
||||
if (!blockState.canSustainPlant(world, pos, Direction.UP, (IPlantable) cropBlock.get()))
|
||||
return;
|
||||
world.setBlockState(pos.up(), cropBlock.get()
|
||||
.getDefaultState(), 3);
|
||||
};
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
@ -164,11 +220,21 @@ public class PotatoCannonProjectileTypes {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder drag(float drag) {
|
||||
result.drag = drag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder reloadTicks(int reload) {
|
||||
result.reloadTicks = reload;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder splitInto(int split) {
|
||||
result.split = split;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder soundPitch(float pitch) {
|
||||
result.fwoompPitch = pitch;
|
||||
return this;
|
||||
|
@ -199,7 +265,7 @@ public class PotatoCannonProjectileTypes {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder onBlockHit(Consumer<BlockRayTraceResult> callback) {
|
||||
public Builder onBlockHit(BiConsumer<IWorld, BlockRayTraceResult> callback) {
|
||||
result.onBlockHit = callback;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package com.simibubi.create.content.curiosities.weapons;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.particle.AirParticleData;
|
||||
import com.simibubi.create.content.curiosities.zapper.ShootableGadgetRenderHandler;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
|
||||
public class PotatoCannonRenderHandler extends ShootableGadgetRenderHandler {
|
||||
|
||||
private float nextPitch;
|
||||
|
||||
@Override
|
||||
protected void playSound(Hand hand, BlockPos position) {
|
||||
PotatoProjectileEntity.playLaunchSound(Minecraft.getInstance().world, position, nextPitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean appliesTo(ItemStack stack) {
|
||||
return AllItems.POTATO_CANNON.get()
|
||||
.isCannon(stack);
|
||||
}
|
||||
|
||||
public void beforeShoot(float nextPitch, Vector3d location, Vector3d motion, ItemStack stack) {
|
||||
this.nextPitch = nextPitch;
|
||||
if (stack.isEmpty())
|
||||
return;
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Vector3d m = VecHelper.offsetRandomly(motion.scale(0.1f), Create.RANDOM, .025f);
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), location.x, location.y, location.z, m.x,
|
||||
m.y, m.z);
|
||||
|
||||
Vector3d m2 = VecHelper.offsetRandomly(motion.scale(2f), Create.RANDOM, .5f);
|
||||
world.addParticle(new AirParticleData(1, 1 / 4f), location.x, location.y, location.z, m2.x, m2.y, m2.z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transformTool(MatrixStack ms, float flip, float equipProgress, float recoil, float pt) {
|
||||
ms.translate(flip * -.1f, 0, .14f);
|
||||
ms.scale(.75f, .75f, .75f);
|
||||
MatrixStacker.of(ms)
|
||||
.rotateX(recoil * 80);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transformHand(MatrixStack ms, float flip, float equipProgress, float recoil, float pt) {
|
||||
ms.translate(flip * -.09, -.275, -.25);
|
||||
MatrixStacker.of(ms)
|
||||
.rotateZ(flip * -10);
|
||||
}
|
||||
|
||||
}
|
|
@ -69,8 +69,9 @@ public class PotatoProjectileEntity extends DamagingProjectileEntity implements
|
|||
}
|
||||
|
||||
public void tick() {
|
||||
setMotion(getMotion().add(0, -.05, 0)
|
||||
.scale(.99f));
|
||||
PotatoCannonProjectileTypes projectileType = getProjectileType();
|
||||
setMotion(getMotion().add(0, -.05 * projectileType.getGravityMultiplier(), 0)
|
||||
.scale(projectileType.getDrag()));
|
||||
super.tick();
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,8 @@ public class PotatoProjectileEntity extends DamagingProjectileEntity implements
|
|||
return;
|
||||
if (owner instanceof LivingEntity)
|
||||
((LivingEntity) owner).setLastAttackedEntity(target);
|
||||
if (target instanceof PotatoProjectileEntity && ticksExisted < 10 && target.ticksExisted < 10)
|
||||
return;
|
||||
|
||||
pop(hit);
|
||||
|
||||
|
@ -164,15 +167,15 @@ public class PotatoProjectileEntity extends DamagingProjectileEntity implements
|
|||
AllSoundEvents.POTATO_HIT.playOnServer(world, new BlockPos(location));
|
||||
}
|
||||
|
||||
public static void playLaunchSound(World world, Vector3d location, float pitch) {
|
||||
AllSoundEvents.FWOOMP.playOnServer(world, new BlockPos(location), 1, pitch);
|
||||
public static void playLaunchSound(World world, BlockPos location, float pitch) {
|
||||
AllSoundEvents.FWOOMP.playAt(world, location, 1, pitch, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockHit(BlockRayTraceResult ray) {
|
||||
Vector3d hit = ray.getHitVec();
|
||||
pop(hit);
|
||||
getProjectileType().onBlockHit(ray);
|
||||
getProjectileType().onBlockHit(world, ray);
|
||||
super.onBlockHit(ray);
|
||||
remove();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package com.simibubi.create.content.curiosities.zapper;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public abstract class ShootGadgetPacket extends SimplePacketBase {
|
||||
|
||||
public Vector3d location;
|
||||
public Hand hand;
|
||||
public boolean self;
|
||||
|
||||
public ShootGadgetPacket(Vector3d location, Hand hand, boolean self) {
|
||||
this.location = location;
|
||||
this.hand = hand;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public ShootGadgetPacket(PacketBuffer buffer) {
|
||||
hand = buffer.readBoolean() ? Hand.MAIN_HAND : Hand.OFF_HAND;
|
||||
self = buffer.readBoolean();
|
||||
location = new Vector3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble());
|
||||
readAdditional(buffer);
|
||||
}
|
||||
|
||||
public final void write(PacketBuffer buffer) {
|
||||
buffer.writeBoolean(hand == Hand.MAIN_HAND);
|
||||
buffer.writeBoolean(self);
|
||||
buffer.writeDouble(location.x);
|
||||
buffer.writeDouble(location.y);
|
||||
buffer.writeDouble(location.z);
|
||||
writeAdditional(buffer);
|
||||
}
|
||||
|
||||
protected abstract void readAdditional(PacketBuffer buffer);
|
||||
|
||||
protected abstract void writeAdditional(PacketBuffer buffer);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected abstract void handleAdditional();
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected abstract ShootableGadgetRenderHandler getHandler();
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
Entity renderViewEntity = Minecraft.getInstance()
|
||||
.getRenderViewEntity();
|
||||
if (renderViewEntity == null)
|
||||
return;
|
||||
if (renderViewEntity.getPositionVec()
|
||||
.distanceTo(location) > 100)
|
||||
return;
|
||||
|
||||
ShootableGadgetRenderHandler handler = getHandler();
|
||||
handleAdditional();
|
||||
if (self)
|
||||
handler.shoot(hand);
|
||||
else
|
||||
handler.playSound(hand, new BlockPos(location));
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.simibubi.create.content.curiosities.zapper;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class ShootableGadgetItemMethods {
|
||||
|
||||
public static void applyCooldown(PlayerEntity player, ItemStack item, Hand hand, Predicate<ItemStack> predicate,
|
||||
int cooldown) {
|
||||
boolean gunInOtherHand =
|
||||
predicate.test(player.getHeldItem(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND));
|
||||
player.getCooldownTracker()
|
||||
.setCooldown(item.getItem(), gunInOtherHand ? cooldown * 2 / 3 : cooldown);
|
||||
}
|
||||
|
||||
public static void sendPackets(PlayerEntity player, Function<Boolean, ? extends ShootGadgetPacket> factory) {
|
||||
if (!(player instanceof ServerPlayerEntity))
|
||||
return;
|
||||
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> player), factory.apply(false));
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), factory.apply(true));
|
||||
}
|
||||
|
||||
public static boolean shouldSwap(PlayerEntity player, ItemStack item, Hand hand, Predicate<ItemStack> predicate) {
|
||||
boolean isSwap = item.getTag()
|
||||
.contains("_Swap");
|
||||
boolean mainHand = hand == Hand.MAIN_HAND;
|
||||
boolean gunInOtherHand = predicate.test(player.getHeldItem(mainHand ? Hand.OFF_HAND : Hand.MAIN_HAND));
|
||||
|
||||
// Pass To Offhand
|
||||
if (mainHand && isSwap && gunInOtherHand)
|
||||
return true;
|
||||
if (mainHand && !isSwap && gunInOtherHand)
|
||||
item.getTag()
|
||||
.putBoolean("_Swap", true);
|
||||
if (!mainHand && isSwap)
|
||||
item.getTag()
|
||||
.remove("_Swap");
|
||||
if (!mainHand && gunInOtherHand)
|
||||
player.getHeldItem(Hand.MAIN_HAND)
|
||||
.getTag()
|
||||
.remove("_Swap");
|
||||
player.setActiveHand(hand);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Vector3d getGunBarrelVec(PlayerEntity player, boolean mainHand, Vector3d rightHandForward) {
|
||||
Vector3d start = player.getPositionVec()
|
||||
.add(0, player.getEyeHeight(), 0);
|
||||
float yaw = (float) ((player.rotationYaw) / -180 * Math.PI);
|
||||
float pitch = (float) ((player.rotationPitch) / -180 * Math.PI);
|
||||
int flip = mainHand == (player.getPrimaryHand() == HandSide.RIGHT) ? -1 : 1;
|
||||
Vector3d barrelPosNoTransform = new Vector3d(flip * rightHandForward.x, rightHandForward.y, rightHandForward.z);
|
||||
Vector3d barrelPos = start.add(barrelPosNoTransform.rotatePitch(pitch)
|
||||
.rotateYaw(yaw));
|
||||
return barrelPos;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package com.simibubi.create.content.curiosities.zapper;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.renderer.FirstPersonRenderer;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.entity.PlayerRenderer;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
|
||||
public abstract class ShootableGadgetRenderHandler {
|
||||
|
||||
protected float leftHandAnimation;
|
||||
protected float rightHandAnimation;
|
||||
protected float lastLeftHandAnimation;
|
||||
protected float lastRightHandAnimation;
|
||||
protected boolean dontReequipLeft;
|
||||
protected boolean dontReequipRight;
|
||||
|
||||
public void tick() {
|
||||
lastLeftHandAnimation = leftHandAnimation;
|
||||
lastRightHandAnimation = rightHandAnimation;
|
||||
leftHandAnimation *= animationDecay();
|
||||
rightHandAnimation *= animationDecay();
|
||||
}
|
||||
|
||||
public float getAnimation(boolean rightHand, float partialTicks) {
|
||||
return MathHelper.lerp(partialTicks, rightHand ? lastRightHandAnimation : lastLeftHandAnimation,
|
||||
rightHand ? rightHandAnimation : leftHandAnimation);
|
||||
}
|
||||
|
||||
protected float animationDecay() {
|
||||
return 0.8f;
|
||||
}
|
||||
|
||||
public void shoot(Hand hand) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
boolean rightHand = hand == Hand.MAIN_HAND ^ player.getPrimaryHand() == HandSide.LEFT;
|
||||
if (rightHand) {
|
||||
rightHandAnimation = .2f;
|
||||
dontReequipRight = false;
|
||||
} else {
|
||||
leftHandAnimation = .2f;
|
||||
dontReequipLeft = false;
|
||||
}
|
||||
playSound(hand, player.getBlockPos());
|
||||
}
|
||||
|
||||
protected abstract void playSound(Hand hand, BlockPos position);
|
||||
|
||||
protected abstract boolean appliesTo(ItemStack stack);
|
||||
|
||||
protected abstract void transformTool(MatrixStack ms, float flip, float equipProgress, float recoil, float pt);
|
||||
|
||||
protected abstract void transformHand(MatrixStack ms, float flip, float equipProgress, float recoil, float pt);
|
||||
|
||||
public void register(IEventBus bus) {
|
||||
bus.addListener(this::onRenderPlayerHand);
|
||||
}
|
||||
|
||||
protected void onRenderPlayerHand(RenderHandEvent event) {
|
||||
ItemStack heldItem = event.getItemStack();
|
||||
if (!appliesTo(heldItem))
|
||||
return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
AbstractClientPlayerEntity player = mc.player;
|
||||
TextureManager textureManager = mc.getTextureManager();
|
||||
PlayerRenderer playerrenderer = (PlayerRenderer) mc.getRenderManager()
|
||||
.getRenderer(player);
|
||||
FirstPersonRenderer firstPersonRenderer = mc.getFirstPersonRenderer();
|
||||
|
||||
MatrixStack ms = event.getMatrixStack();
|
||||
IRenderTypeBuffer buffer = event.getBuffers();
|
||||
int light = event.getLight();
|
||||
float pt = event.getPartialTicks();
|
||||
|
||||
boolean rightHand = event.getHand() == Hand.MAIN_HAND ^ mc.player.getPrimaryHand() == HandSide.LEFT;
|
||||
float recoil = rightHand ? MathHelper.lerp(pt, lastRightHandAnimation, rightHandAnimation)
|
||||
: MathHelper.lerp(pt, lastLeftHandAnimation, leftHandAnimation);
|
||||
float equipProgress = event.getEquipProgress();
|
||||
|
||||
if (rightHand && (rightHandAnimation > .01f || dontReequipRight))
|
||||
equipProgress = 0;
|
||||
if (!rightHand && (leftHandAnimation > .01f || dontReequipLeft))
|
||||
equipProgress = 0;
|
||||
|
||||
// Render arm
|
||||
ms.push();
|
||||
textureManager.bindTexture(player.getLocationSkin());
|
||||
|
||||
float flip = rightHand ? 1.0F : -1.0F;
|
||||
float f1 = MathHelper.sqrt(event.getSwingProgress());
|
||||
float f2 = -0.3F * MathHelper.sin(f1 * (float) Math.PI);
|
||||
float f3 = 0.4F * MathHelper.sin(f1 * ((float) Math.PI * 2F));
|
||||
float f4 = -0.4F * MathHelper.sin(event.getSwingProgress() * (float) Math.PI);
|
||||
float f5 = MathHelper.sin(event.getSwingProgress() * event.getSwingProgress() * (float) Math.PI);
|
||||
float f6 = MathHelper.sin(f1 * (float) Math.PI);
|
||||
|
||||
ms.translate(flip * (f2 + 0.64F - .1f), f3 + -0.4F + equipProgress * -0.6F, f4 + -0.72F + .3f + recoil);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * 75.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * f6 * 70.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(flip * f5 * -20.0F));
|
||||
ms.translate(flip * -1.0F, 3.6F, 3.5F);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(flip * 120.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(200.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * -135.0F));
|
||||
ms.translate(flip * 5.6F, 0.0F, 0.0F);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * 40.0F));
|
||||
transformHand(ms, flip, equipProgress, recoil, pt);
|
||||
if (rightHand)
|
||||
playerrenderer.renderRightArm(ms, buffer, light, player);
|
||||
else
|
||||
playerrenderer.renderLeftArm(ms, buffer, light, player);
|
||||
ms.pop();
|
||||
|
||||
// Render gadget
|
||||
ms.push();
|
||||
ms.translate(flip * (f2 + 0.64F - .1f), f3 + -0.4F + equipProgress * -0.6F, f4 + -0.72F - 0.1f + recoil);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * f6 * 70.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(flip * f5 * -20.0F));
|
||||
transformTool(ms, flip, equipProgress, recoil, pt);
|
||||
firstPersonRenderer.renderItem(mc.player, heldItem,
|
||||
rightHand ? ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND
|
||||
: ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND,
|
||||
!rightHand, ms, buffer, light);
|
||||
ms.pop();
|
||||
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
public void dontAnimateItem(Hand hand) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
boolean rightHand = hand == Hand.MAIN_HAND ^ player.getPrimaryHand() == HandSide.LEFT;
|
||||
dontReequipRight |= rightHand;
|
||||
dontReequipLeft |= !rightHand;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +1,49 @@
|
|||
package com.simibubi.create.content.curiosities.zapper;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler.LaserBeam;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class ZapperBeamPacket extends SimplePacketBase {
|
||||
public class ZapperBeamPacket extends ShootGadgetPacket {
|
||||
|
||||
public Vector3d start;
|
||||
public Vector3d target;
|
||||
public Hand hand;
|
||||
public boolean self;
|
||||
|
||||
public ZapperBeamPacket(Vector3d start, Vector3d target, Hand hand, boolean self) {
|
||||
this.start = start;
|
||||
super(start, hand, self);
|
||||
this.target = target;
|
||||
this.hand = hand;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public ZapperBeamPacket(PacketBuffer buffer) {
|
||||
start = new Vector3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble());
|
||||
target = new Vector3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble());
|
||||
hand = buffer.readBoolean()? Hand.MAIN_HAND : Hand.OFF_HAND;
|
||||
self = buffer.readBoolean();
|
||||
}
|
||||
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeDouble(start.x);
|
||||
buffer.writeDouble(start.y);
|
||||
buffer.writeDouble(start.z);
|
||||
public ZapperBeamPacket(PacketBuffer buffer) {
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditional(PacketBuffer buffer) {
|
||||
target = new Vector3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeAdditional(PacketBuffer buffer) {
|
||||
buffer.writeDouble(target.x);
|
||||
buffer.writeDouble(target.y);
|
||||
buffer.writeDouble(target.z);
|
||||
|
||||
buffer.writeBoolean(hand == Hand.MAIN_HAND);
|
||||
buffer.writeBoolean(self);
|
||||
}
|
||||
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
if (Minecraft.getInstance().player.getPositionVec().distanceTo(start) > 100)
|
||||
return;
|
||||
ZapperRenderHandler.addBeam(new LaserBeam(start, target).followPlayer(self, hand == Hand.MAIN_HAND));
|
||||
|
||||
if (self)
|
||||
ZapperRenderHandler.shoot(hand);
|
||||
else
|
||||
ZapperRenderHandler.playSound(hand, new BlockPos(start));
|
||||
}));
|
||||
context.get().setPacketHandled(true);
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected ShootableGadgetRenderHandler getHandler() {
|
||||
return CreateClient.ZAPPER_RENDER_HANDLER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected void handleAdditional() {
|
||||
CreateClient.ZAPPER_RENDER_HANDLER.addBeam(new LaserBeam(location, target));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import javax.annotation.Nonnull;
|
|||
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||
|
@ -17,7 +17,6 @@ import net.minecraft.block.Blocks;
|
|||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
|
@ -28,7 +27,6 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceContext;
|
||||
|
@ -43,7 +41,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public abstract class ZapperItem extends Item {
|
||||
|
||||
|
@ -95,7 +92,10 @@ public abstract class ZapperItem extends Item {
|
|||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
openHandgunGUI(context.getItem(), context.getHand() == Hand.OFF_HAND);
|
||||
});
|
||||
applyCooldown(context.getPlayer(), context.getItem(), false);
|
||||
context.getPlayer()
|
||||
.getCooldownTracker()
|
||||
.setCooldown(context.getItem()
|
||||
.getItem(), 10);
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ public abstract class ZapperItem extends Item {
|
|||
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
|
||||
ItemStack item = player.getHeldItem(hand);
|
||||
CompoundNBT nbt = item.getOrCreateTag();
|
||||
boolean mainHand = hand == Hand.MAIN_HAND;
|
||||
|
||||
// Shift -> Open GUI
|
||||
if (player.isSneaking()) {
|
||||
|
@ -113,36 +114,21 @@ public abstract class ZapperItem extends Item {
|
|||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
openHandgunGUI(item, hand == Hand.OFF_HAND);
|
||||
});
|
||||
applyCooldown(player, item, false);
|
||||
player.getCooldownTracker()
|
||||
.setCooldown(item.getItem(), 10);
|
||||
}
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, item);
|
||||
}
|
||||
|
||||
boolean mainHand = hand == Hand.MAIN_HAND;
|
||||
boolean isSwap = item.getTag()
|
||||
.contains("_Swap");
|
||||
boolean gunInOtherHand = isZapper(player.getHeldItem(mainHand ? Hand.OFF_HAND : Hand.MAIN_HAND));
|
||||
|
||||
// Pass To Offhand
|
||||
if (mainHand && isSwap && gunInOtherHand)
|
||||
if (ShootableGadgetItemMethods.shouldSwap(player, item, hand, this::isZapper))
|
||||
return new ActionResult<>(ActionResultType.FAIL, item);
|
||||
if (mainHand && !isSwap && gunInOtherHand)
|
||||
item.getTag()
|
||||
.putBoolean("_Swap", true);
|
||||
if (!mainHand && isSwap)
|
||||
item.getTag()
|
||||
.remove("_Swap");
|
||||
if (!mainHand && gunInOtherHand)
|
||||
player.getHeldItem(Hand.MAIN_HAND)
|
||||
.getTag()
|
||||
.remove("_Swap");
|
||||
player.setActiveHand(hand);
|
||||
|
||||
// Check if can be used
|
||||
ITextComponent msg = validateUsage(item);
|
||||
if (msg != null) {
|
||||
AllSoundEvents.DENY.play(world, player, player.getBlockPos());
|
||||
player.sendStatusMessage(msg.copy().formatted(TextFormatting.RED), true);
|
||||
player.sendStatusMessage(msg.copy()
|
||||
.formatted(TextFormatting.RED), true);
|
||||
return new ActionResult<>(ActionResultType.FAIL, item);
|
||||
}
|
||||
|
||||
|
@ -167,31 +153,24 @@ public abstract class ZapperItem extends Item {
|
|||
|
||||
// No target
|
||||
if (pos == null || stateReplaced.getBlock() == Blocks.AIR) {
|
||||
applyCooldown(player, item, gunInOtherHand);
|
||||
ShootableGadgetItemMethods.applyCooldown(player, item, hand, this::isZapper, getCooldownDelay(item));
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, item);
|
||||
}
|
||||
|
||||
// Find exact position of gun barrel for VFX
|
||||
float yaw = (float) ((player.rotationYaw) / -180 * Math.PI);
|
||||
float pitch = (float) ((player.rotationPitch) / -180 * Math.PI);
|
||||
Vector3d barrelPosNoTransform =
|
||||
new Vector3d(mainHand == (player.getPrimaryHand() == HandSide.RIGHT) ? -.35f : .35f, -0.1f, 1);
|
||||
Vector3d barrelPos = start.add(barrelPosNoTransform.rotatePitch(pitch)
|
||||
.rotateYaw(yaw));
|
||||
Vector3d barrelPos = ShootableGadgetItemMethods.getGunBarrelVec(player, mainHand, new Vector3d(.35f, -0.1f, 1));
|
||||
|
||||
// Client side
|
||||
if (world.isRemote) {
|
||||
ZapperRenderHandler.dontAnimateItem(hand);
|
||||
CreateClient.ZAPPER_RENDER_HANDLER.dontAnimateItem(hand);
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, item);
|
||||
}
|
||||
|
||||
// Server side
|
||||
if (activate(world, player, item, stateToUse, raytrace, data)) {
|
||||
applyCooldown(player, item, gunInOtherHand);
|
||||
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> player),
|
||||
new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, false));
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player),
|
||||
new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, true));
|
||||
ShootableGadgetItemMethods.applyCooldown(player, item, hand, this::isZapper, getCooldownDelay(item));
|
||||
ShootableGadgetItemMethods.sendPackets(player,
|
||||
b -> new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, b));
|
||||
}
|
||||
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, item);
|
||||
|
@ -218,12 +197,6 @@ public abstract class ZapperItem extends Item {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void applyCooldown(PlayerEntity playerIn, ItemStack item, boolean dual) {
|
||||
int delay = getCooldownDelay(item);
|
||||
playerIn.getCooldownTracker()
|
||||
.setCooldown(item.getItem(), dual ? delay * 2 / 3 : delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEntitySwing(ItemStack stack, LivingEntity entity) {
|
||||
return true;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.curiosities.zapper;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
|
||||
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
|
||||
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
|
||||
|
@ -50,12 +51,8 @@ public abstract class ZapperItemRenderer<M extends CustomRenderedItemModel> exte
|
|||
}
|
||||
|
||||
protected float getAnimationProgress(float pt, boolean leftHanded, boolean mainHand) {
|
||||
float last = mainHand ^ leftHanded ? ZapperRenderHandler.lastRightHandAnimation
|
||||
: ZapperRenderHandler.lastLeftHandAnimation;
|
||||
float current =
|
||||
mainHand ^ leftHanded ? ZapperRenderHandler.rightHandAnimation : ZapperRenderHandler.leftHandAnimation;
|
||||
float animation = MathHelper.clamp(MathHelper.lerp(pt, last, current) * 5, 0, 1);
|
||||
return animation;
|
||||
float animation = CreateClient.ZAPPER_RENDER_HANDLER.getAnimation(mainHand ^ leftHanded, pt);
|
||||
return MathHelper.clamp(animation * 5, 0, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,79 +8,28 @@ import java.util.function.Supplier;
|
|||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.renderer.FirstPersonRenderer;
|
||||
import net.minecraft.client.renderer.entity.PlayerRenderer;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ZapperRenderHandler {
|
||||
public class ZapperRenderHandler extends ShootableGadgetRenderHandler {
|
||||
|
||||
public static List<LaserBeam> cachedBeams;
|
||||
public static float leftHandAnimation;
|
||||
public static float rightHandAnimation;
|
||||
public static float lastLeftHandAnimation;
|
||||
public static float lastRightHandAnimation;
|
||||
public List<LaserBeam> cachedBeams;
|
||||
|
||||
private static boolean dontReequipLeft;
|
||||
private static boolean dontReequipRight;
|
||||
|
||||
public static class LaserBeam {
|
||||
float itensity;
|
||||
Vector3d start;
|
||||
Vector3d end;
|
||||
boolean follow;
|
||||
boolean mainHand;
|
||||
|
||||
public LaserBeam(Vector3d start, Vector3d end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
itensity = 1;
|
||||
}
|
||||
|
||||
public LaserBeam followPlayer(boolean follow, boolean mainHand) {
|
||||
this.follow = follow;
|
||||
this.mainHand = mainHand;
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
protected boolean appliesTo(ItemStack stack) {
|
||||
return stack.getItem() instanceof ZapperItem;
|
||||
}
|
||||
|
||||
public static Vector3d getExactBarrelPos(boolean mainHand) {
|
||||
float partialTicks = AnimationTickHolder.getPartialTicks();
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
float yaw = (float) ((player.getYaw(partialTicks)) / -180 * Math.PI);
|
||||
float pitch = (float) ((player.getPitch(partialTicks)) / -180 * Math.PI);
|
||||
boolean rightHand = mainHand == (player.getPrimaryHand() == HandSide.RIGHT);
|
||||
float zOffset = ((float) Minecraft.getInstance().gameSettings.fov - 70) / -100;
|
||||
Vector3d barrelPosNoTransform = new Vector3d(rightHand ? -.35f : .35f, -0.115f, .75f + zOffset);
|
||||
Vector3d barrelPos = player.getEyePosition(partialTicks)
|
||||
.add(barrelPosNoTransform.rotatePitch(pitch)
|
||||
.rotateYaw(yaw));
|
||||
return barrelPos;
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
lastLeftHandAnimation = leftHandAnimation;
|
||||
lastRightHandAnimation = rightHandAnimation;
|
||||
leftHandAnimation *= 0.8f;
|
||||
rightHandAnimation *= 0.8f;
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (cachedBeams == null)
|
||||
cachedBeams = new LinkedList<>();
|
||||
|
@ -91,34 +40,31 @@ public class ZapperRenderHandler {
|
|||
|
||||
cachedBeams.forEach(beam -> {
|
||||
CreateClient.OUTLINER.endChasingLine(beam, beam.start, beam.end, 1 - beam.itensity)
|
||||
.disableNormals()
|
||||
.colored(0xffffff)
|
||||
.lineWidth(beam.itensity * 1 / 8f);
|
||||
.disableNormals()
|
||||
.colored(0xffffff)
|
||||
.lineWidth(beam.itensity * 1 / 8f);
|
||||
});
|
||||
|
||||
cachedBeams.forEach(b -> b.itensity *= .6f);
|
||||
}
|
||||
|
||||
public static void shoot(Hand hand) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
boolean rightHand = hand == Hand.MAIN_HAND ^ player.getPrimaryHand() == HandSide.LEFT;
|
||||
if (rightHand) {
|
||||
rightHandAnimation = .2f;
|
||||
dontReequipRight = false;
|
||||
} else {
|
||||
leftHandAnimation = .2f;
|
||||
dontReequipLeft = false;
|
||||
}
|
||||
playSound(hand, player.getBlockPos());
|
||||
@Override
|
||||
protected void transformTool(MatrixStack ms, float flip, float equipProgress, float recoil, float pt) {
|
||||
ms.translate(flip * -0.1f, 0.1f, -0.4f);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(flip * 5.0F));
|
||||
}
|
||||
|
||||
public static void playSound(Hand hand, BlockPos position) {
|
||||
@Override
|
||||
protected void transformHand(MatrixStack ms, float flip, float equipProgress, float recoil, float pt) {}
|
||||
|
||||
@Override
|
||||
protected void playSound(Hand hand, BlockPos position) {
|
||||
float pitch = hand == Hand.MAIN_HAND ? 0.1f : 0.9f;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
AllSoundEvents.WORLDSHAPER_PLACE.play(mc.world, mc.player, position, 0.1f, pitch);
|
||||
}
|
||||
|
||||
public static void addBeam(LaserBeam beam) {
|
||||
public void addBeam(LaserBeam beam) {
|
||||
Random r = new Random();
|
||||
double x = beam.end.x;
|
||||
double y = beam.end.y;
|
||||
|
@ -135,87 +81,16 @@ public class ZapperRenderHandler {
|
|||
cachedBeams.add(beam);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderPlayerHand(RenderHandEvent event) {
|
||||
ItemStack heldItem = event.getItemStack();
|
||||
if (!(heldItem.getItem() instanceof ZapperItem))
|
||||
return;
|
||||
public static class LaserBeam {
|
||||
float itensity;
|
||||
Vector3d start;
|
||||
Vector3d end;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
boolean rightHand = event.getHand() == Hand.MAIN_HAND ^ mc.player.getPrimaryHand() == HandSide.LEFT;
|
||||
|
||||
MatrixStack ms = event.getMatrixStack();
|
||||
|
||||
ms.push();
|
||||
float recoil = rightHand ? MathHelper.lerp(event.getPartialTicks(), lastRightHandAnimation, rightHandAnimation)
|
||||
: MathHelper.lerp(event.getPartialTicks(), lastLeftHandAnimation, leftHandAnimation);
|
||||
|
||||
float equipProgress = event.getEquipProgress();
|
||||
|
||||
if (rightHand && (rightHandAnimation > .01f || dontReequipRight))
|
||||
equipProgress = 0;
|
||||
if (!rightHand && (leftHandAnimation > .01f || dontReequipLeft))
|
||||
equipProgress = 0;
|
||||
|
||||
// Render arm
|
||||
float f = rightHand ? 1.0F : -1.0F;
|
||||
float f1 = MathHelper.sqrt(event.getSwingProgress());
|
||||
float f2 = -0.3F * MathHelper.sin(f1 * (float) Math.PI);
|
||||
float f3 = 0.4F * MathHelper.sin(f1 * ((float) Math.PI * 2F));
|
||||
float f4 = -0.4F * MathHelper.sin(event.getSwingProgress() * (float) Math.PI);
|
||||
float f5 = MathHelper.sin(event.getSwingProgress() * event.getSwingProgress() * (float) Math.PI);
|
||||
float f6 = MathHelper.sin(f1 * (float) Math.PI);
|
||||
|
||||
ms.translate(f * (f2 + 0.64000005F - .1f), f3 + -0.4F + equipProgress * -0.6F,
|
||||
f4 + -0.71999997F + .3f + recoil);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * 75.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * f6 * 70.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(f * f5 * -20.0F));
|
||||
AbstractClientPlayerEntity abstractclientplayerentity = mc.player;
|
||||
mc.getTextureManager()
|
||||
.bindTexture(abstractclientplayerentity.getLocationSkin());
|
||||
ms.translate(f * -1.0F, 3.6F, 3.5F);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(f * 120.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(200.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * -135.0F));
|
||||
ms.translate(f * 5.6F, 0.0F, 0.0F);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * 40.0F));
|
||||
|
||||
PlayerRenderer playerrenderer = (PlayerRenderer) mc.getRenderManager()
|
||||
.getRenderer(abstractclientplayerentity);
|
||||
if (rightHand) {
|
||||
playerrenderer.renderRightArm(event.getMatrixStack(), event.getBuffers(), event.getLight(),
|
||||
abstractclientplayerentity);
|
||||
} else {
|
||||
playerrenderer.renderLeftArm(event.getMatrixStack(), event.getBuffers(), event.getLight(),
|
||||
abstractclientplayerentity);
|
||||
public LaserBeam(Vector3d start, Vector3d end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
itensity = 1;
|
||||
}
|
||||
ms.pop();
|
||||
|
||||
// Render gun
|
||||
ms.push();
|
||||
ms.translate(f * (f2 + 0.64000005F - .1f), f3 + -0.4F + equipProgress * -0.6F,
|
||||
f4 + -0.71999997F - 0.1f + recoil);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * f6 * 70.0F));
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(f * f5 * -20.0F));
|
||||
|
||||
ms.translate(f * -0.1f, 0.1f, -0.4f);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(f * 5.0F));
|
||||
|
||||
FirstPersonRenderer firstPersonRenderer = mc.getFirstPersonRenderer();
|
||||
firstPersonRenderer.renderItem(mc.player, heldItem,
|
||||
rightHand ? ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND
|
||||
: ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND,
|
||||
!rightHand, event.getMatrixStack(), event.getBuffers(), event.getLight());
|
||||
ms.pop();
|
||||
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
public static void dontAnimateItem(Hand hand) {
|
||||
boolean rightHand = hand == Hand.MAIN_HAND ^ Minecraft.getInstance().player.getPrimaryHand() == HandSide.LEFT;
|
||||
dontReequipRight |= rightHand;
|
||||
dontReequipLeft |= !rightHand;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.simibubi.create.events;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.AllFluids;
|
||||
|
@ -30,7 +29,6 @@ import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer;
|
|||
import com.simibubi.create.content.curiosities.tools.ExtendoGripRenderHandler;
|
||||
import com.simibubi.create.content.curiosities.weapons.PotatoCannonItem;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperItem;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler;
|
||||
import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperRenderHandler;
|
||||
import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler;
|
||||
|
@ -117,6 +115,8 @@ public class ClientEvents {
|
|||
CreateClient.SCHEMATIC_SENDER.tick();
|
||||
CreateClient.SCHEMATIC_AND_QUILL_HANDLER.tick();
|
||||
CreateClient.SCHEMATIC_HANDLER.tick();
|
||||
CreateClient.ZAPPER_RENDER_HANDLER.tick();
|
||||
CreateClient.POTATO_CANNON_RENDER_HANDLER.tick();
|
||||
|
||||
ContraptionHandler.tick(world);
|
||||
CapabilityMinecartController.tick(world);
|
||||
|
@ -135,7 +135,6 @@ public class ClientEvents {
|
|||
CouplingHandlerClient.tick();
|
||||
CouplingRenderer.tickDebugModeRenders();
|
||||
KineticDebugger.tick();
|
||||
ZapperRenderHandler.tick();
|
||||
ExtendoGripRenderHandler.tick();
|
||||
// CollisionDebugger.tick();
|
||||
ArmInteractionPointHandler.tick();
|
||||
|
|
Loading…
Reference in a new issue