-
Notifications
You must be signed in to change notification settings - Fork 911
Extract common code from bow and crossbow #5351
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
base: 1.20.1
Are you sure you want to change the base?
Changes from 2 commits
4310d52
61fa8dc
8cf8dec
01b1c9e
6463f63
cf33ccc
6bb0ef9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,21 +100,21 @@ private static ItemStack findMatchingAmmo(ItemStack bow, LivingEntity living, Pr | |
| * @param tool Tool instance | ||
| * @param bow Bow stack instance | ||
| * @param predicate Predicate for valid ammo | ||
| * @param player Player to search | ||
| * @param user User to search | ||
| * @return Found ammo | ||
| */ | ||
| static ItemStack findAmmo(IToolStackView tool, ItemStack bow, Player player, Predicate<ItemStack> predicate) { | ||
| static ItemStack findAmmo(IToolStackView tool, ItemStack bow, LivingEntity user, Predicate<ItemStack> predicate) { | ||
| int projectilesDesired = 1 + (2 * tool.getModifierLevel(TinkerModifiers.multishot.getId())); | ||
| // treat client side as creative, no need to shrink the stacks clientside | ||
| Level level = player.level(); | ||
| boolean creative = player.getAbilities().instabuild || level.isClientSide; | ||
| Level level = user.level(); | ||
| boolean creative = user instanceof Player player && player.getAbilities().instabuild || level.isClientSide; | ||
|
|
||
| // first search, find what ammo type we want | ||
| ItemStack standardAmmo = player.getProjectile(bow); | ||
| ItemStack standardAmmo = user.getProjectile(bow); | ||
| ItemStack resultStack = ItemStack.EMPTY; | ||
| for (ModifierEntry entry : tool.getModifierList()) { | ||
| BowAmmoModifierHook hook = entry.getHook(ModifierHooks.BOW_AMMO); | ||
| ItemStack ammo = hook.findAmmo(tool, entry, player, standardAmmo, predicate); | ||
| ItemStack ammo = hook.findAmmo(tool, entry, user, standardAmmo, predicate); | ||
| if (!ammo.isEmpty()) { | ||
| // if creative, we are done, just return the ammo with the given size | ||
| if (creative) { | ||
|
|
@@ -123,7 +123,7 @@ static ItemStack findAmmo(IToolStackView tool, ItemStack bow, Player player, Pre | |
|
|
||
| // not creative, split out the desired amount. We may have to do more work if it is too small | ||
| resultStack = ItemHandlerHelper.copyStackWithSize(ammo, Math.min(projectilesDesired, ammo.getCount())); | ||
| hook.shrinkAmmo(tool, entry, player, ammo, resultStack.getCount()); | ||
| hook.shrinkAmmo(tool, entry, user, ammo, resultStack.getCount()); | ||
| break; | ||
| } | ||
| } | ||
|
|
@@ -140,7 +140,7 @@ static ItemStack findAmmo(IToolStackView tool, ItemStack bow, Player player, Pre | |
| } | ||
| // make a copy of the result, up to the desired size | ||
| resultStack = standardAmmo.split(projectilesDesired); | ||
| if (standardAmmo.isEmpty()) { | ||
| if (standardAmmo.isEmpty() && user instanceof Player player) { | ||
| player.getInventory().removeItem(standardAmmo); | ||
| } | ||
| } | ||
|
|
@@ -159,17 +159,17 @@ static ItemStack findAmmo(IToolStackView tool, ItemStack bow, Player player, Pre | |
| do { | ||
| // if standard ammo is empty, try finding a matching stack again | ||
| if (standardAmmo.isEmpty()) { | ||
| standardAmmo = findMatchingAmmo(bow, player, predicate); | ||
| standardAmmo = findMatchingAmmo(bow, user, predicate); | ||
| } | ||
| // next, try asking modifiers if they have anything new again | ||
| int needed = projectilesDesired - resultStack.getCount(); | ||
| for (ModifierEntry entry : tool.getModifierList()) { | ||
| BowAmmoModifierHook hook = entry.getHook(ModifierHooks.BOW_AMMO); | ||
| ItemStack ammo = hook.findAmmo(tool, entry, player, standardAmmo, predicate); | ||
| ItemStack ammo = hook.findAmmo(tool, entry, user, standardAmmo, predicate); | ||
| if (!ammo.isEmpty()) { | ||
| // consume as much of the stack as we need then continue, loop condition will stop if we are now done | ||
| int gained = Math.min(needed, ammo.getCount()); | ||
| hook.shrinkAmmo(tool, entry, player, ammo, gained); | ||
| hook.shrinkAmmo(tool, entry, user, ammo, gained); | ||
| resultStack.grow(gained); | ||
| continue hasEnough; | ||
| } | ||
|
|
@@ -183,7 +183,10 @@ static ItemStack findAmmo(IToolStackView tool, ItemStack bow, Player player, Pre | |
| if (needed > standardAmmo.getCount()) { | ||
| // consume the whole stack | ||
| resultStack.grow(standardAmmo.getCount()); | ||
| player.getInventory().removeItem(standardAmmo); | ||
| standardAmmo.setCount(0); | ||
| if (user instanceof Player player) { | ||
| player.getInventory().removeItem(standardAmmo); | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to discuss this more; how is a non-player expected to remove the ammo from their inventory? Or are we just assuming they don't care about cleaning up empty stacks? I know most mobs do infinite ammo, but imagine a dispenser like shooter.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say the mob needs to be able to clean up empty stacks themselves. What harm will it do to not remove empty stacks? They are empty and
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mostly just memory waste, which is why vanilla typically does it.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there is a realistic method to clear mob inventory, as each mob would have different implementations. Sounds like it doesn't matter that much. Though if you think this part should be part of the API, then maybe |
||
| standardAmmo = ItemStack.EMPTY; | ||
| } else { | ||
| // found what we need, we are done | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package slimeknights.tconstruct.library.tools.item.ranged; | ||
|
|
||
| import net.minecraft.world.entity.LivingEntity; | ||
| import net.minecraft.world.entity.player.Player; | ||
| import net.minecraft.world.level.Level; | ||
|
|
||
| public interface LauncherUserInfo { | ||
|
lcy0x1 marked this conversation as resolved.
Outdated
|
||
|
|
||
| static LauncherUserInfo playerLike(LivingEntity user, float speed) { | ||
| return new PlayerLike(user, speed); | ||
| } | ||
|
|
||
| LivingEntity user(); | ||
|
|
||
| default Level level() { | ||
| return user().level(); | ||
| } | ||
|
|
||
| /** | ||
| * regular arrow speed at full charge. 3 for player with bow. 1.6 for skeletons. 3.15 for crossbows. | ||
| */ | ||
| float speedFactor(); | ||
|
|
||
| /** | ||
| * shoot inaccuracy factor. 1 for player, and hostile mobs use a complex formula involving difficulty. | ||
| */ | ||
| float inaccuracyFactor(); | ||
|
|
||
| /** | ||
| * Whether to make the arrow marked as no-pickup. True for infinite arrows or hostile mob arrows. | ||
| */ | ||
| boolean infinite(); | ||
|
|
||
| /** | ||
| * Whether to damage weapon. True for hostile mobs. | ||
| */ | ||
| boolean damageWeapon(); | ||
|
|
||
| record PlayerLike(LivingEntity user, float speedFactor) implements LauncherUserInfo { | ||
|
|
||
| @Override | ||
| public float inaccuracyFactor() { | ||
| return 1; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean infinite() { | ||
| return user instanceof Player player && player.getAbilities().instabuild; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean damageWeapon() { | ||
| return !infinite(); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.