Skip to content

Commit

Permalink
Double scarf gravity again, add trinket slot to stapler, add slot ico…
Browse files Browse the repository at this point in the history
…ns, improve API
  • Loading branch information
falkreon committed Sep 13, 2022
1 parent b5db44f commit 0e1da10
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 12 deletions.
48 changes: 48 additions & 0 deletions src/main/java/blue/endless/scarves/ScarvesApiImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package blue.endless.scarves;

import java.util.ArrayList;

import blue.endless.scarves.api.FabricSquare;
import blue.endless.scarves.api.FabricSquareRegistry;
import blue.endless.scarves.api.ScarvesApi;
import blue.endless.scarves.api.WindVectorProvider;
import net.minecraft.block.Block;
import net.minecraft.item.ItemConvertible;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;

public class ScarvesApiImpl implements ScarvesApi {
private static ScarvesApiImpl INSTANCE = new ScarvesApiImpl();

private ArrayList<WindVectorProvider> windProviders = new ArrayList<>();

public static ScarvesApiImpl getInstance() {
return INSTANCE;
}

@Override
public void register(Block block, String textureId) {
FabricSquareRegistry.register(block, textureId);
}

@Override
public void register(ItemConvertible item, FabricSquare square) {
FabricSquareRegistry.register(item, square);
}

@Override
public void provideWind(WindVectorProvider wind) {
windProviders.add(wind);
}

@Override
public Vec3d getWind(World world, Vec3d pos) {
Vec3d result = new Vec3d(0,0,0);

for(WindVectorProvider provider : windProviders) {
result = result.add(provider.apply(world, pos));
}

return result;
}
}
3 changes: 3 additions & 0 deletions src/main/java/blue/endless/scarves/ScarvesMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import blue.endless.scarves.api.ScarvesApi;
import blue.endless.scarves.api.ScarvesIntegration;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
Expand All @@ -18,6 +19,7 @@ public class ScarvesMod implements ModInitializer {

public static ItemGroup ITEM_GROUP;

@SuppressWarnings("removal")
@Override
public void onInitialize() {
ITEM_GROUP = FabricItemGroupBuilder
Expand All @@ -32,6 +34,7 @@ public void onInitialize() {
for (EntrypointContainer<ScarvesIntegration> entrypoint : FabricLoader.getInstance().getEntrypointContainers(MODID, ScarvesIntegration.class)) {
try {
entrypoint.getEntrypoint().integrateWithScarves();
entrypoint.getEntrypoint().integrateWithScarves(ScarvesApi.instance());
} catch (Throwable t) {
LOGGER.error("Mod '"+entrypoint.getProvider().getMetadata().getId()+"' threw an exception trying to activate Scarves integration.", t);
}
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/blue/endless/scarves/api/ScarfLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import blue.endless.scarves.ScarvesApiImpl;
import blue.endless.scarves.client.ScarfAttachment;
import blue.endless.scarves.client.ScarfNode;
import blue.endless.scarves.client.ScarvesClient;
Expand All @@ -12,6 +13,7 @@
import net.minecraft.world.World;

public class ScarfLogic {
public static double maxWindMagnitude = 0.5;

/**
* Updates the ScarfAttachment with new scarf data and applies gravity. Should be called each tick by an IScarfHaver.
Expand All @@ -32,13 +34,29 @@ public static void updateScarfAttachment(ScarfAttachment attachment, World world
}

ScarfNode node = nodes.get(i);
node.setLastPosition(node.getPosition());
Vec3d prospectivePosition = node.getPosition().add(0, ScarvesClient.SCARF_GRAVITY, 0);
BlockPos blockInThatPosition = new BlockPos(prospectivePosition.add(0,-ScarfNode.FABRIC_SQUARE_WIDTH,0));
if (world!=null) {
if (!world.isTopSolid(blockInThatPosition, entity)) {
node.setPosition(prospectivePosition);
}
}

Vec3d wind = ScarvesApiImpl.getInstance().getWind(world, node.getPosition());
//cap wind
if (wind.lengthSquared()>maxWindMagnitude*maxWindMagnitude) {
wind = wind.normalize().multiply(maxWindMagnitude);
}

//move it
prospectivePosition = node.getPosition().add(wind);
blockInThatPosition = new BlockPos(prospectivePosition);
if (world!=null) {
if (!world.isTopSolid(blockInThatPosition, entity)) {
node.setPosition(prospectivePosition);
}
}
}
}

Expand All @@ -57,6 +75,21 @@ public static void updateGravityOnly(ScarfAttachment attachment, World world, En
node.setPosition(prospectivePosition);
}
}

Vec3d wind = ScarvesApiImpl.getInstance().getWind(world, node.getPosition());
//cap wind
if (wind.lengthSquared()>maxWindMagnitude*maxWindMagnitude) {
wind = wind.normalize().multiply(maxWindMagnitude);
}

//move it
prospectivePosition = node.getPosition().add(wind);
blockInThatPosition = new BlockPos(prospectivePosition);
if (world!=null) {
if (!world.isTopSolid(blockInThatPosition, entity)) {
node.setPosition(prospectivePosition);
}
}
}
}
}
55 changes: 55 additions & 0 deletions src/main/java/blue/endless/scarves/api/ScarvesApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package blue.endless.scarves.api;

import blue.endless.scarves.ScarvesApiImpl;
import net.minecraft.block.Block;
import net.minecraft.item.ItemConvertible;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;

public interface ScarvesApi {

public static ScarvesApi instance() {
return ScarvesApiImpl.getInstance();
}

//API

/**
* Registers a block and allows it to be used in the left or right slots of the Scarf Stapler. The center of the
* texture will be used for the appearance of the square.
*
* <p>Notes: Animated textures, and textures that have been synthetically stitched into the texture atlas used for
* blocks and items, will all work seamlessly. Glowing blocks will automatically be rendered emissively.
* Substituting a different texture from the atlas, a vanilla texture, a texture from a namespace you do not own,
* these things are ALL ALLOWED. Cut out the middle of the diamond pickaxe texture and put it on a square, I'm not
* your dad. Basically, if you can figure out its name, it's fair game. Putting any invalid identifier, including
* "", will result in the pink checkers we all know and love.
*
* @param block The block to be accepted as a Fabric Square by the Scarf Stapler in its left or right slot.
* @param textureId The resulting fabric square's appearance. For example, if you use cube_all, the same identifier
* string that you use for the "all" texture parameter in the block's model will work here.
*/
void register(Block block, String textureId);

/**
* Registers a block, item, or other item-like object and allows it to be used in the left or right slots of the
* Scarf Stapler. The appearance of the square will be governed completely by the FabricSquare provided.
*
* <p>See Also: {@link #register(Block, String)}
*
* @param item The item or item-like object to be accepted as a Fabric Square by the Scarf Stapler in its left or
* right slot.
* @param square The appearance this item should have when stitched to the end of a scarf.
*/
public void register(ItemConvertible item, FabricSquare square);

/**
* Registers a wind provider. These providers let Scarves know about wind that may vary based on location in the
* world. This allows scarves to move in unison with other wind-affected objects, or serve as indicators of strong
* winds for mods which provide windmills.
* @param wind A function which yields a Vec3d of wind direction/strength at the provided world location.
*/
public void provideWind(WindVectorProvider wind);

public Vec3d getWind(World world, Vec3d pos);
}
17 changes: 13 additions & 4 deletions src/main/java/blue/endless/scarves/api/ScarvesIntegration.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package blue.endless.scarves.api;

/**
* This interface can be registered as an entrypoint with the "scarves" id, in order to do mod interop things, such as
* making your blocks/items work in the Scarf Stapler, or letting Scarves know which way the wind
* is blowing.
*/
public interface ScarvesIntegration {
/**
* The main thing you can do here is safely call {@link FabricSquareRegistry#register(net.minecraft.block.Block, net.minecraft.util.Identifier)}
*
* <p>Set this class aside and don't touch it, and when this method is called register your blocks as fabric squares!
* Retained for ModFest compatibility. Please move to {@link #integrateWithScarves(ScarvesApi)} as soon as possible.
*/
void integrateWithScarves();
@Deprecated(forRemoval = true)
default void integrateWithScarves() {}

/**
* Allows you to call methods on ScarvesApi without worrying about a hard dependency!
*/
default void integrateWithScarves(ScarvesApi api) {}
}
10 changes: 10 additions & 0 deletions src/main/java/blue/endless/scarves/api/WindVectorProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package blue.endless.scarves.api;

import java.util.function.BiFunction;

import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;

@FunctionalInterface
public interface WindVectorProvider extends BiFunction<World, Vec3d, Vec3d> {
}
21 changes: 20 additions & 1 deletion src/main/java/blue/endless/scarves/client/ScarfNode.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blue.endless.scarves.client;

import blue.endless.scarves.api.FabricSquare;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;

public class ScarfNode {
Expand All @@ -9,11 +10,13 @@ public class ScarfNode {
/** Maximum d^2 allowed between fabric squares; the squared width of a square. */
public static final float SQUARED_WIDTH = FABRIC_SQUARE_WIDTH * FABRIC_SQUARE_WIDTH;
protected Vec3d position;
protected Vec3d velocity;
protected Vec3d lastPosition;
//protected Vec3d velocity;
protected FabricSquare square;

public ScarfNode(Vec3d pos, FabricSquare square) {
this.position = pos;
this.lastPosition = pos;
this.square = square;
};

Expand All @@ -29,10 +32,26 @@ public Vec3d getPosition() {
return position;
}

public Vec3d getLastPosition() {
return lastPosition;
}

public void setPosition(Vec3d pos) {
position = pos;
}

public void setLastPosition(Vec3d pos) {
lastPosition = pos;
}

public Vec3d getLerpedPosition(double deltaTime) {
return new Vec3d(
MathHelper.lerp(deltaTime, lastPosition.x, position.x),
MathHelper.lerp(deltaTime, lastPosition.y, position.y),
MathHelper.lerp(deltaTime, lastPosition.z, position.z)
);
}

public void setSquare(FabricSquare square) {
this.square = square;
}
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/blue/endless/scarves/client/ScarvesClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import net.minecraft.world.LightType;

public class ScarvesClient implements ClientModInitializer {
public static final double SCARF_GRAVITY = -0.005;
public static final double SCARF_GRAVITY = -0.01;

@Override
public void onInitializeClient() {
Expand Down Expand Up @@ -61,9 +61,10 @@ public static void beforeEntities(WorldRenderContext ctx) {
Vec3d prevUp = new Vec3d(0,1,0).multiply(ScarfNode.FABRIC_SQUARE_WIDTH);
for(int i=0; i<nodes.size(); i++) {
ScarfNode cur = nodes.get(i);
Vec3d lerpedPos = cur.getLerpedPosition(ctx.tickDelta());

BlockPos curPos = new BlockPos(cur.position.add(0,0.25,0));
Vec3d forwardVec = cur.position.subtract(prev).normalize();
BlockPos curPos = new BlockPos(lerpedPos.add(0,0.25,0));
Vec3d forwardVec = lerpedPos.subtract(prev).normalize();
Vec3d tempUpVec = (forwardVec.x==0&&forwardVec.z==0) ? new Vec3d(1,0,0) : new Vec3d(0,1,0);
Vec3d rightVec = forwardVec.crossProduct(tempUpVec);
Vec3d curUp = forwardVec.crossProduct(rightVec).multiply(ScarfNode.FABRIC_SQUARE_WIDTH);
Expand All @@ -81,8 +82,8 @@ public static void beforeEntities(WorldRenderContext ctx) {
prev.add(prevUp),
//prev.add(0,ScarfNode.FABRIC_SQUARE_WIDTH,0),
//cur.position.add(0,ScarfNode.FABRIC_SQUARE_WIDTH,0),
cur.position.add(curUp),
cur.position,
lerpedPos.add(curUp),
lerpedPos,

cur.square,

Expand All @@ -91,7 +92,7 @@ public static void beforeEntities(WorldRenderContext ctx) {
nodeLight
);

prev = cur.position;
prev = lerpedPos;
prevUp = curUp;
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
package blue.endless.scarves.gui;

import java.util.Map;

import blue.endless.scarves.ScarfStaplerBlockEntity;
import blue.endless.scarves.ScarvesBlocks;
import blue.endless.scarves.ScarvesItems;
import blue.endless.scarves.ScarvesMod;
import blue.endless.scarves.api.FabricSquareRegistry;
import dev.emi.trinkets.api.TrinketInventory;
import dev.emi.trinkets.api.TrinketsApi;
import io.github.cottonmc.cotton.gui.SyncedGuiDescription;
import io.github.cottonmc.cotton.gui.networking.NetworkSide;
import io.github.cottonmc.cotton.gui.networking.ScreenNetworking;
import io.github.cottonmc.cotton.gui.widget.WButton;
import io.github.cottonmc.cotton.gui.widget.WGridPanel;
import io.github.cottonmc.cotton.gui.widget.WItemSlot;
import io.github.cottonmc.cotton.gui.widget.data.Insets;
import io.github.cottonmc.cotton.gui.widget.icon.TextureIcon;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

public class ScarfStaplerGuiDescription extends SyncedGuiDescription{
public static final Identifier SCARF_SLOT_ICON = new Identifier(ScarvesMod.MODID, "textures/gui/slots/scarf.png");
public static final Identifier SQUARE_SLOT_ICON = new Identifier(ScarvesMod.MODID, "textures/gui/slots/square.png");
public static final Identifier STAPLE_MESSAGE = new Identifier(ScarvesMod.MODID, "ok_staple");

public ScarfStaplerGuiDescription(int syncId, PlayerInventory playerInventory, ScreenHandlerContext context) {
super(ScarvesBlocks.SCARF_STAPLER_SCREEN_HANDLER, syncId, playerInventory, getBlockInventory(context, 3), getBlockPropertyDelegate(context));

//Register the
//Register the staple message
ScreenNetworking.of(this, NetworkSide.SERVER).receive(STAPLE_MESSAGE, this::staple);

WGridPanel root = new WGridPanel();
Expand All @@ -35,14 +42,17 @@ public ScarfStaplerGuiDescription(int syncId, PlayerInventory playerInventory, S

WItemSlot itemSlot = WItemSlot.of(blockInventory, ScarfStaplerBlockEntity.SCARF_SLOT);
itemSlot.setFilter(it->it.isOf(ScarvesItems.SCARF));
itemSlot.setIcon(new TextureIcon(SCARF_SLOT_ICON));
root.add(itemSlot, 4, 2);

WItemSlot leftSlot = WItemSlot.of(blockInventory, ScarfStaplerBlockEntity.LEFT_SLOT);
leftSlot.setFilter(FabricSquareRegistry::canBeStapled);
leftSlot.setIcon(new TextureIcon(SQUARE_SLOT_ICON));
root.add(leftSlot, 2, 2);

WItemSlot rightSlot = WItemSlot.of(blockInventory, ScarfStaplerBlockEntity.RIGHT_SLOT);
rightSlot.setFilter(FabricSquareRegistry::canBeStapled);
rightSlot.setIcon(new TextureIcon(SQUARE_SLOT_ICON));
root.add(rightSlot, 6, 2);

WButton stapleButton = new WButton(Text.translatable("gui.scarves.staple"));
Expand All @@ -52,6 +62,18 @@ public ScarfStaplerGuiDescription(int syncId, PlayerInventory playerInventory, S
root.add(stapleButton, 2, 3, 5, 1);

root.add(this.createPlayerInventoryPanel(), 0, 5);

Map<String, Map<String, TrinketInventory>> inventoryMap = TrinketsApi.getTrinketComponent(playerInventory.player).get().getInventory();
Map<String, TrinketInventory> chestGroup = inventoryMap.get("chest");
if (chestGroup!=null) {
TrinketInventory scarfInventory = chestGroup.get("scarf");
if (scarfInventory!=null && scarfInventory.size()>0) {
WItemSlot playerScarfSlot = WItemSlot.of(scarfInventory, 0);
playerScarfSlot.setFilter(it->it.isOf(ScarvesItems.SCARF));
playerScarfSlot.setIcon(new TextureIcon(SCARF_SLOT_ICON));
root.add(playerScarfSlot, 0, 4);
}
}

root.validate(this);
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0e1da10

Please sign in to comment.