diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/ModEnglishLanguageProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/ModEnglishLanguageProvider.java index b8c59f2e1..2b309d4db 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/ModEnglishLanguageProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/ModEnglishLanguageProvider.java @@ -169,6 +169,7 @@ protected void addTranslations() { addDamageTranslations(); addTooltip("empty", "Empty"); + addTooltip("contains", "Contains: %1$s"); addTooltip("nutrients_fuel", "Nutrients"); addTooltip("nutrients_consumes", "Consumes %1$s u"); addTooltip("consumption", "Consumption"); @@ -178,14 +179,17 @@ protected void addTranslations() { addTooltip("action_self_inject", "inject yourself"); addTooltip("action_self_extract", "extract from yourself"); addTooltip("action_open_inventory", "open its inventory"); + addTooltip("fire_rate", "Fire Rate"); addTooltip("accuracy", "Accuracy"); addTooltip("ammo", "Ammo"); addTooltip("reload_time", "Reload Time"); addTooltip("projectile_damage", "Projectile Damage"); + addTooltip("item_is_dormant", "The Tool is Dormant"); addTooltip("item_is_awake", "The Tool is Awake"); addTooltip("item_is_exalted", "The Tool is Exalted"); + addTooltip("dormant", "Dormant"); addTooltip("awake", "Awake"); addTooltip("exalted", "Exalted"); diff --git a/src/generated/resources/assets/biomancy/lang/en_us.json b/src/generated/resources/assets/biomancy/lang/en_us.json index cf5a771e9..97ad39f86 100644 --- a/src/generated/resources/assets/biomancy/lang/en_us.json +++ b/src/generated/resources/assets/biomancy/lang/en_us.json @@ -350,6 +350,7 @@ "tooltip.biomancy.awake": "Awake", "tooltip.biomancy.bile_fuel": "Bile", "tooltip.biomancy.consumption": "Consumption", + "tooltip.biomancy.contains": "Contains: %1$s", "tooltip.biomancy.contains_unique_dna": "Contains Unique Genetic Sequences", "tooltip.biomancy.dormant": "Dormant", "tooltip.biomancy.empty": "Empty", diff --git a/src/main/java/com/github/elenterius/biomancy/world/item/InjectorItem.java b/src/main/java/com/github/elenterius/biomancy/world/item/InjectorItem.java index b21e01751..e9ec3fa40 100644 --- a/src/main/java/com/github/elenterius/biomancy/world/item/InjectorItem.java +++ b/src/main/java/com/github/elenterius/biomancy/world/item/InjectorItem.java @@ -144,153 +144,103 @@ public InteractionResultHolder onClientKeyPress(ItemStack stack, Level lev @Override public void onServerReceiveKeyPress(ItemStack stack, ServerLevel level, Player player, byte flags) { if (flags == -2) { - //clear out whole inventory - getItemHandler(stack).ifPresent(handler -> { - if (!handler.getStack().isEmpty()) { - ItemStack result = handler.extractItem(handler.getMaxAmount(), false); - if (!player.addItem(result)) { - player.drop(result, false); - } - } - }); + clearInventory(stack, player); } if (flags >= 0) { - //replace whole inventory with new item - final int idx = flags; - ItemStack foundStack = player.getInventory().getItem(idx); - Item item = foundStack.getItem(); - if (item instanceof ISerumProvider && !(item instanceof InjectorItem)) { - getItemHandler(stack).ifPresent(handler -> { - ItemStack oldStack = ItemStack.EMPTY; - if (!handler.getStack().isEmpty()) { - oldStack = handler.extractItem(handler.getMaxAmount(), false); - } - - ItemStack remainder = handler.insertItem(foundStack, false); - player.getInventory().setItem(idx, remainder); - - //eject old stuff - if (!oldStack.isEmpty() && !player.addItem(oldStack)) { - player.drop(oldStack, false); - } - }); - } + setInventory(stack, player, flags); } } - @Override - public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { - if (player.isShiftKeyDown()) { - ItemStack stack = player.getItemInHand(usedHand); - if (player.getCooldowns().isOnCooldown(this)) return InteractionResultHolder.fail(stack); - - if (interactWithPlayerSelf(stack, player)) { - if (!level.isClientSide) { - scheduleSerumInjection(stack, player, player, SCHEDULE_TICKS); - broadcastAnimation((ServerLevel) level, player, stack, AnimState.INJECT_SELF.id); - player.getCooldowns().addCooldown(this, COOL_DOWN_TICKS); - } - return InteractionResultHolder.consume(stack); - } - - SoundUtil.playItemSoundEffect(level, player, ModSoundEvents.INJECTOR_FAIL); - return InteractionResultHolder.fail(stack); + /** + * replace contents of injector inventory with new item from player inventory + */ + private void setInventory(ItemStack injector, Player player, int slotIndex) { + ItemStack foundStack = player.getInventory().getItem(slotIndex); - } - return InteractionResultHolder.pass(player.getItemInHand(usedHand)); - } + Item item = foundStack.getItem(); + if (item instanceof InjectorItem) return; + if (!(item instanceof ISerumProvider)) return; - @Override - public InteractionResult interactLivingEntity(ItemStack copyOfStack, Player player, LivingEntity target, InteractionHand usedHand) { - Serum serum = getSerum(copyOfStack); - if (serum != null) { - if (MobUtil.canPierceThroughArmor(copyOfStack, target)) { - CompoundTag dataTag = Serum.getDataTag(copyOfStack); - if (serum.canAffectEntity(dataTag, player, target)) { - if (player.level.isClientSide) return InteractionResult.CONSUME; + getItemHandler(injector).ifPresent(handler -> { + ItemStack oldStack = ItemStack.EMPTY; + if (!handler.getStack().isEmpty()) { + oldStack = handler.extractItem(handler.getMaxAmount(), false); + } - if (player.getCooldowns().isOnCooldown(this)) return InteractionResult.FAIL; - player.getCooldowns().addCooldown(this, COOL_DOWN_TICKS); + ItemStack remainder = handler.insertItem(foundStack, false); + player.getInventory().setItem(slotIndex, remainder); - ItemStack realStack = player.getAbilities().instabuild ? player.getItemInHand(usedHand) : copyOfStack; - scheduleSerumInjection(realStack, player, target, SCHEDULE_TICKS); - broadcastAnimation((ServerLevel) target.level, player, realStack, AnimState.INJECT_OTHER.id); + //eject old stuff + if (!oldStack.isEmpty() && !player.addItem(oldStack)) { + player.drop(oldStack, false); + } + }); + } - return InteractionResult.CONSUME; + private void clearInventory(ItemStack injector, Player player) { + getItemHandler(injector).ifPresent(handler -> { + if (!handler.getStack().isEmpty()) { + ItemStack result = handler.extractItem(handler.getMaxAmount(), false); + if (!player.addItem(result)) { + player.drop(result, false); } } - else if (!player.level.isClientSide) { - copyOfStack.hurtAndBreak(2, player, p -> p.broadcastBreakEvent(EquipmentSlot.MAINHAND)); - } - - if (player.level.isClientSide) SoundUtil.clientPlayItemSound(player.level, player, ModSoundEvents.INJECTOR_FAIL.get()); - return InteractionResult.FAIL; - } - - return InteractionResult.PASS; + }); } @Override - public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) { - if (entity instanceof ServerPlayer player && level instanceof ServerLevel serverLevel) { - tickInjectionScheduler(serverLevel, stack, player); - } - } - - private void scheduleSerumInjection(ItemStack stack, Player player, LivingEntity target, int delayInTicks) { - if (stack.isEmpty() || player.level.isClientSide || getSerum(stack) == null) return; + public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { + ItemStack stack = player.getItemInHand(usedHand); - setEntityHost(stack, player); //who is using the item - setEntityVictim(stack, target); //who is the victim + if (!player.isShiftKeyDown()) return InteractionResultHolder.pass(stack); + if (player.getCooldowns().isOnCooldown(this) || !canInteractWithPlayerSelf(stack, player)) { + SoundUtil.playItemSoundEffect(level, player, ModSoundEvents.INJECTOR_FAIL); + return InteractionResultHolder.fail(stack); + } - CompoundTag tag = stack.getOrCreateTag(); - tag.putInt("DelayInTicks", delayInTicks); - tag.putLong("ScheduleTimestamp", player.level.getGameTime()); + if (!level.isClientSide) { + InjectionScheduler.schedule(this, stack, player, player, SCHEDULE_TICKS); + broadcastAnimation((ServerLevel) level, player, stack, AnimState.INJECT_SELF.id); + player.getCooldowns().addCooldown(this, COOL_DOWN_TICKS); + } + return InteractionResultHolder.consume(stack); } - private void tickInjectionScheduler(ServerLevel level, ItemStack stack, ServerPlayer player) { - CompoundTag tag = stack.getOrCreateTag(); - if (!tag.contains("ScheduleTimestamp")) return; - - long delayInTicks = tag.getLong("DelayInTicks"); - long starTimestamp = tag.getLong("ScheduleTimestamp"); - if (player.level.getGameTime() - starTimestamp > delayInTicks) { - performScheduledSerumInjection(level, stack, player); - tag.remove("DelayInTicks"); - tag.remove("ScheduleTimestamp"); - } + public boolean canInteractWithPlayerSelf(ItemStack stack, Player player) { + Serum serum = getSerum(stack); + return serum != null && serum.canAffectPlayerSelf(Serum.getDataTag(stack), player); } - private void performScheduledSerumInjection(ServerLevel level, ItemStack stack, ServerPlayer player) { + public boolean canInteractWithLivingTarget(ItemStack stack, Player player, LivingEntity target) { Serum serum = getSerum(stack); - if (serum != null) { - Entity victim = getEntityVictim(stack, level); - Entity host = getEntityHost(stack, level); - if (victim instanceof LivingEntity target) { - if (host == victim) { - serum.affectPlayerSelf(Serum.getDataTag(stack), player); - } - else { - serum.affectEntity(level, Serum.getDataTag(stack), player, target); - } - } - consumeSerum(stack, player); - stack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(EquipmentSlot.MAINHAND)); + return serum != null && serum.canAffectEntity(Serum.getDataTag(stack), player, target); + } + + @Override + public InteractionResult interactLivingEntity(ItemStack copyOfStack, Player player, LivingEntity target, InteractionHand usedHand) { + if (!canInteractWithLivingTarget(copyOfStack, player, target)) { + if (player.level.isClientSide) SoundUtil.clientPlayItemSound(player.level, player, ModSoundEvents.INJECTOR_FAIL.get()); + return InteractionResult.FAIL; } + + if (player.level.isClientSide) return InteractionResult.CONSUME; + if (player.getCooldowns().isOnCooldown(this)) return InteractionResult.FAIL; + + player.getCooldowns().addCooldown(this, COOL_DOWN_TICKS); + + ItemStack realStack = player.getAbilities().instabuild ? player.getItemInHand(usedHand) : copyOfStack; + InjectionScheduler.schedule(this, realStack, player, target, SCHEDULE_TICKS); + broadcastAnimation((ServerLevel) target.level, player, realStack, AnimState.INJECT_OTHER.id); + + return InteractionResult.CONSUME; } - public boolean interactWithPlayerSelf(ItemStack stack, Player player) { - Serum serum = getSerum(stack); - if (serum != null) { - if (MobUtil.canPierceThroughArmor(stack, player)) { - return serum.canAffectPlayerSelf(Serum.getDataTag(stack), player); - } - else if (!player.level.isClientSide) { - stack.hurtAndBreak(2, player, p -> p.broadcastBreakEvent(EquipmentSlot.MAINHAND)); - } + @Override + public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) { + if (entity instanceof ServerPlayer player && level instanceof ServerLevel serverLevel) { + InjectionScheduler.tick(serverLevel, this, stack, player); } - return false; } @Override @@ -480,6 +430,7 @@ else if (AnimState.INJECT_SELF.is(state)) { public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltip, TooltipFlag isAdvanced) { tooltip.add(TooltipHacks.HR_COMPONENT); tooltip.add(ClientTextUtil.getItemInfoTooltip(stack.getItem())); + tooltip.add(TooltipHacks.EMPTY_LINE_COMPONENT); CompoundTag tag = stack.getOrCreateTag(); if (tag.contains(INVENTORY_TAG)) { @@ -546,4 +497,62 @@ public LazyOptional getCapability(@NotNull Capability capability, @Nul } + static class InjectionScheduler { + + public static final String DELAY_KEY = "DelayInTicks"; + public static final String TIMESTAMP_KEY = "ScheduleTimestamp"; + private InjectionScheduler() {} + + public static void schedule(InjectorItem injector, ItemStack stack, Player player, LivingEntity target, int delayInTicks) { + if (stack.isEmpty() || player.level.isClientSide || injector.getSerum(stack) == null) return; + + injector.setEntityHost(stack, player); //who is using the item + injector.setEntityVictim(stack, target); //who is the victim + + CompoundTag tag = stack.getOrCreateTag(); + tag.putInt(DELAY_KEY, delayInTicks); + tag.putLong(TIMESTAMP_KEY, player.level.getGameTime()); + } + + public static void tick(ServerLevel level, InjectorItem injector, ItemStack stack, ServerPlayer player) { + CompoundTag tag = stack.getOrCreateTag(); + if (!tag.contains(TIMESTAMP_KEY)) return; + + long delayInTicks = tag.getLong(DELAY_KEY); + long starTimestamp = tag.getLong(TIMESTAMP_KEY); + if (player.level.getGameTime() - starTimestamp > delayInTicks) { + performScheduledSerumInjection(level, injector, stack, player); + tag.remove(DELAY_KEY); + tag.remove(TIMESTAMP_KEY); + } + } + + public static void performScheduledSerumInjection(ServerLevel level, InjectorItem injector, ItemStack stack, ServerPlayer player) { + Serum serum = injector.getSerum(stack); + if (serum == null) return; + + Entity victim = injector.getEntityVictim(stack, level); + Entity host = injector.getEntityHost(stack, level); + + if (victim instanceof LivingEntity target) { + if (!MobUtil.canPierceThroughArmor(stack, target)) { + stack.hurtAndBreak(2, player, p -> {}); + player.broadcastBreakEvent(EquipmentSlot.MAINHAND); //break needle + player.getCooldowns().addCooldown(stack.getItem(), COOL_DOWN_TICKS * 2); + return; + } + + if (host == victim) { + serum.affectPlayerSelf(Serum.getDataTag(stack), player); + } + else { + serum.affectEntity(level, Serum.getDataTag(stack), player, target); + } + + injector.consumeSerum(stack, player); + stack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(EquipmentSlot.MAINHAND)); + } + } + } + } diff --git a/src/main/java/com/github/elenterius/biomancy/world/serum/InsomniaCureSerum.java b/src/main/java/com/github/elenterius/biomancy/world/serum/InsomniaCureSerum.java index e559da2ca..a05d48970 100644 --- a/src/main/java/com/github/elenterius/biomancy/world/serum/InsomniaCureSerum.java +++ b/src/main/java/com/github/elenterius/biomancy/world/serum/InsomniaCureSerum.java @@ -34,7 +34,7 @@ public boolean canAffectPlayerSelf(CompoundTag tag, Player targetSelf) { // if (!targetSelf.level.isClientSide && !targetSelf.level.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) return false; if (getTimeSinceRest(targetSelf) > 20 * 60) { - if (targetSelf.level.isClientSide) { + if (!targetSelf.level.isClientSide) { targetSelf.displayClientMessage(TextComponentUtil.getFailureMsgText("not_sleepy"), true); } return false; diff --git a/src/main/resources/assets/biomancy/models/item/injector.json b/src/main/resources/assets/biomancy/models/item/injector.json index d1890969a..cbb21c4fa 100644 --- a/src/main/resources/assets/biomancy/models/item/injector.json +++ b/src/main/resources/assets/biomancy/models/item/injector.json @@ -70,6 +70,9 @@ } } }, + "textures": { + "particle": "biomancy:item/component/bone_fragments" + }, "perspectives": { "gui": { "parent": "biomancy:item/injector_icon"