Skip to content

Commit

Permalink
refactor: refactor bio-injector item
Browse files Browse the repository at this point in the history
  • Loading branch information
Elenterius committed Dec 24, 2022
1 parent 7d4ea54 commit 012c242
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/generated/resources/assets/biomancy/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
249 changes: 129 additions & 120 deletions src/main/java/com/github/elenterius/biomancy/world/item/InjectorItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,153 +144,103 @@ public InteractionResultHolder<Byte> 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<ItemStack> 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<ItemStack> 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
Expand Down Expand Up @@ -480,6 +430,7 @@ else if (AnimState.INJECT_SELF.is(state)) {
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> 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)) {
Expand Down Expand Up @@ -546,4 +497,62 @@ public <T> LazyOptional<T> getCapability(@NotNull Capability<T> 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));
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/assets/biomancy/models/item/injector.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
}
}
},
"textures": {
"particle": "biomancy:item/component/bone_fragments"
},
"perspectives": {
"gui": {
"parent": "biomancy:item/injector_icon"
Expand Down

0 comments on commit 012c242

Please sign in to comment.