Skip to content

Commit

Permalink
Ensure that Astrolabe doesn't do its work "for free"
Browse files Browse the repository at this point in the history
If blocks are provided by mana-consuming items, calculations for the number of available blocks may be off if the player is short on mana.
As long as preliminary checks suggest that enough blocks should be available, the Astrolabe will now consume its operation mana first and then only place the blocks that can actually be conjured with the remaining mana.
  • Loading branch information
TheRealWormbo authored and williewillus committed May 29, 2023
1 parent 8d17442 commit e4ae46b
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 69 deletions.
47 changes: 29 additions & 18 deletions Xplat/src/main/java/vazkii/botania/common/item/AstrolabeItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
import net.minecraft.world.phys.HitResult;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.item.BlockProvider;
import vazkii.botania.api.mana.ManaItemHandler;
import vazkii.botania.client.gui.ItemsRemainingRenderHandler;
Expand All @@ -53,6 +53,7 @@ public class AstrolabeItem extends Item {

public static final String TAG_BLOCKSTATE = "blockstate";
public static final String TAG_SIZE = "size";
public static final int BASE_COST = 320;

public AstrolabeItem(Properties props) {
super(props);
Expand Down Expand Up @@ -111,41 +112,53 @@ public boolean placeAllBlocks(ItemStack requester, Player player, InteractionHan
return false;
}

int cost = size * 320;
if (!ManaItemHandler.instance().requestManaExact(requester, player, cost, false)) {
int cost = size * BASE_COST;
if (!ManaItemHandler.instance().requestManaExact(requester, player, cost, true)) {
return false;
}

for (BlockPos coords : placePositions) {
!placeBlockAndConsume(requester, blockToPlace, ctx, coords, blockProviders)) {
if (!placeBlockAndConsume(requester, blockToPlace, ctx, coords, blockProviders)) {
break;
}
}
ManaItemHandler.instance().requestManaExact(requester, player, cost, true);

return true;
}

private void placeBlockAndConsume(ItemStack requester, Block blockToPlace, BlockPlaceContext ctx,
/**
* Attempts to place the specified block and consume it from the player's inventory.
*
* @return {@code true} if continuing to attempt placing blocks makes sense,
* {@code false} if not, e.g. because there are fewer blocks available than expected.
*/
private boolean placeBlockAndConsume(ItemStack requester, Block blockToPlace, BlockPlaceContext ctx,
BlockPos pos, List<BlockProvider> providers) {
final Player player = ctx.getPlayer();
if (player == null) {
return;
return false;
}

BlockState state = blockToPlace.getStateForPlacement(ctx);
if (state == null) {
return;
return true;
}

if (providers.stream().noneMatch(prov -> prov.provideBlock(player, requester, blockToPlace, false))) {
// don't place blocks we don't have (e.g. because mana calculations were inaccurate somehow)
return false;
}

UseOnContext useOnContext = RingOfLokiItem.getUseOnContext(player, ctx.getHand(), pos, ctx.getClickLocation(), ctx.getClickedFace());
if (!PlayerHelper.substituteUse(useOnContext, new ItemStack(blockToPlace)).consumesAction()) {
return;
return true;
}
for (BlockProvider prov : providers) {
if (prov.provideBlock(player, requester, blockToPlace, true)) {
return;
break;
}
}
BotaniaAPI.LOGGER.debug("All providers failed to provide a block");
return true;
}

public static boolean hasBlocks(ItemStack requester, Player player, int required, Block block) {
Expand All @@ -166,7 +179,7 @@ public static List<BlockProvider> findBlockProviders(ItemStack requester, Player

int current = 0;
List<BlockProvider> providersToCheck = new ArrayList<>();
for (int i = 0; i < player.getInventory().getContainerSize() && current < required; i++) {
for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
ItemStack stackInSlot = player.getInventory().getItem(i);
if (stackInSlot.isEmpty()) {
continue;
Expand All @@ -183,17 +196,14 @@ public static List<BlockProvider> findBlockProviders(ItemStack requester, Player
current += count;
providersToCheck.add(provider);
}
if (count == -1) {
// found an infinite provider, so definitely enough blocks
return providersToCheck;
}
}
}
}

return current >= required ? providersToCheck : List.of();
}

@Nullable
public static BlockPlaceContext getBlockPlaceContext(Player player, InteractionHand hand, Block blockToPlace) {
if (blockToPlace == Blocks.AIR) {
return null;
Expand Down Expand Up @@ -257,15 +267,16 @@ public void displayRemainderCounter(Player player, ItemStack stack) {
}
}

private boolean setBlock(ItemStack stack, BlockState state) {
public static boolean setBlock(ItemStack stack, BlockState state) {
if (!state.isAir()) {
// This stores a block state (instead of just the block ID) for legacy reasons.
ItemNBTHelper.setCompound(stack, TAG_BLOCKSTATE, NbtUtils.writeBlockState(state.getBlock().defaultBlockState()));
return true;
}
return false;
}

private static void setSize(ItemStack stack, int size) {
public static void setSize(ItemStack stack, int size) {
ItemNBTHelper.setInt(stack, TAG_SIZE, size | 1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public Component getName(@NotNull ItemStack stack) {
return cand;
}

private static boolean setBlock(ItemStack stack, Block block) {
public static boolean setBlock(ItemStack stack, Block block) {
if (block.asItem() != Items.AIR && (getBlock(stack) == null || getBlockCount(stack) == 0)) {
ItemNBTHelper.setString(stack, TAG_BLOCK_NAME, Registry.BLOCK.getKey(block).toString());
return true;
Expand Down Expand Up @@ -208,7 +208,7 @@ public void appendHoverText(ItemStack stack, Level world, List<Component> stacks
}
}

private static void setCount(ItemStack stack, int count) {
public static void setCount(ItemStack stack, int count) {
ItemNBTHelper.setInt(stack, TAG_BLOCK_COUNT, count);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

public class DepthsRodItem extends Item {

static final int COST = 150;
public static final int COST = 150;

public DepthsRodItem(Properties props) {
super(props);
Expand Down
Loading

0 comments on commit e4ae46b

Please sign in to comment.