Skip to content

Commit

Permalink
Merge Staff Mod 0.15.0
Browse files Browse the repository at this point in the history
  • Loading branch information
opekope2 authored Jun 10, 2024
2 parents 61d8a59 + d8af4f0 commit 5073b31
Show file tree
Hide file tree
Showing 164 changed files with 4,305 additions and 4,165 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
- name: JDK setup
uses: actions/[email protected]
with:
java-version: 17
java-version: 21
distribution: temurin
- name: Build project
if: inputs.build-project
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
NeoForgeMod/build/libs/*.jar
if-no-files-found: error
- name: Upload Forge jars
if: inputs.build-project && inputs.upload-output
if: inputs.build-project && inputs.upload-output && false
uses: actions/[email protected]
with:
name: forge-jars
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
name: neoforge-jars
path: dist/neoforge
- name: Download Forge jars
if: false
uses: actions/[email protected]
with:
name: forge-jars
Expand Down Expand Up @@ -95,6 +96,7 @@ jobs:
game-version-filter: releases
java: ${{ steps.load-java-version.outputs.value }}
- name: Publish Forge mod to Modrinth and CurseForge
if: false
uses: Kir-Antipov/[email protected]
with:
modrinth-id: ${{ vars.MODRINTH_ID }}
Expand Down Expand Up @@ -123,16 +125,13 @@ jobs:
dist/fabric/*-@(dev|sources|javadoc).jar
dist/neoforge/!(*-@(dev|sources|javadoc)).jar
dist/neoforge/*-@(dev|sources|javadoc).jar
dist/forge/!(*-@(dev|sources|javadoc)).jar
dist/forge/*-@(dev|sources|javadoc).jar
changelog-file: CHANGELOG.g.md
- name: Delete build output
uses: geekyeggo/[email protected]
with:
name: |
fabric-jars
neoforge-jars
forge-jars
useGlob: false
failOnError: false

Expand Down
20 changes: 20 additions & 0 deletions FabricMod/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* AvM Staff Mod
* Copyright (c) 2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

plugins {
alias(libs.plugins.shadow)
}
Expand Down Expand Up @@ -77,6 +95,7 @@ tasks {

from(rootDir.resolve("COPYING"))
from(rootDir.resolve("COPYING.LESSER"))
from(rootDir.resolve("README.md"))
}

remapJar {
Expand All @@ -87,6 +106,7 @@ tasks {

from(rootDir.resolve("COPYING"))
from(rootDir.resolve("COPYING.LESSER"))
from(rootDir.resolve("README.md"))
}

sourcesJar {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* AvM Staff Mod
* Copyright (c) 2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

package opekope2.avm_staff.mixin.fabric;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import opekope2.avm_staff.api.StaffMod;
import opekope2.avm_staff.api.staff.StaffHandler;
import opekope2.avm_staff.util.StaffUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin extends Entity {
private LivingEntityMixin(EntityType<?> type, World world) {
super(type, world);
}

@Shadow
public abstract ItemStack getMainHandStack();

@Shadow
public abstract ItemStack getStackInHand(Hand hand);

@Inject(method = "disablesShield", at = @At("HEAD"), cancellable = true)
public void disableShield(CallbackInfoReturnable<Boolean> cir) {
ItemStack mainHandStack = getMainHandStack();
if (!mainHandStack.isIn(StaffMod.getStaffsTag())) return;

Item itemInStaff = StaffUtil.getItemInStaff(mainHandStack);
if (itemInStaff == null) return;

StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrDefault(itemInStaff);
if (handlerOfItem.disablesShield()) {
cir.setReturnValue(true);
}
}

@SuppressWarnings("UnreachableCode") // Calm down IDEA, this is not what it looks like. Literally
@Inject(method = "swingHand(Lnet/minecraft/util/Hand;Z)V", at = @At("HEAD"), cancellable = true)
public void swingHand(Hand hand, boolean fromServerPlayer, CallbackInfo ci) {
ItemStack stackInHand = getStackInHand(hand);
if (stackInHand.isEmpty()) return;
if (!stackInHand.isIn(StaffMod.getStaffsTag())) return;

Item itemInStaff = StaffUtil.getItemInStaff(stackInHand);
if (itemInStaff == null) return;

StaffHandler handlerOfItem = StaffUtil.getStaffHandlerOrDefault(itemInStaff);
if (!handlerOfItem.canSwingHand(stackInHand, getEntityWorld(), (LivingEntity) (Object) this, hand)) {
ci.cancel();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* AvM Staff Mod
* Copyright (c) 2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

package opekope2.avm_staff.mixin.fabric;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.PiglinBrain;
import net.minecraft.item.ItemStack;
import opekope2.avm_staff.api.item.CrownItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(PiglinBrain.class)
public abstract class PiglinBrainMixin {
@Inject(method = "wearsGoldArmor", at = @At("HEAD"), cancellable = true)
private static void wearsGoldArmor(LivingEntity entity, CallbackInfoReturnable<Boolean> cir) {
for (ItemStack armorStack : entity.getArmorItems()) {
if (armorStack.getItem() instanceof CrownItem) {
cir.setReturnValue(true);
return;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,72 +18,41 @@

package opekope2.avm_staff.internal.fabric

import net.fabricmc.api.EnvType
import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.event.player.AttackBlockCallback
import net.fabricmc.fabric.api.event.player.AttackEntityCallback
import net.fabricmc.fabric.api.item.v1.FabricItemSettings
import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes
import net.fabricmc.loader.api.FabricLoader
import net.minecraft.entity.Entity
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.Item
import net.minecraft.particle.DefaultParticleType
import net.minecraft.registry.Registries
import net.minecraft.registry.Registry
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.tag.TagKey
import net.minecraft.util.ActionResult
import net.minecraft.util.Hand
import net.minecraft.util.Identifier
import net.minecraft.util.hit.EntityHitResult
import net.minecraft.world.World
import opekope2.avm_staff.IStaffMod
import opekope2.avm_staff.api.item.StaffItem
import opekope2.avm_staff.internal.event_handler.attackBlock
import opekope2.avm_staff.internal.event_handler.attackEntity
import opekope2.avm_staff.internal.fabric.item.FabricStaffItem
import opekope2.avm_staff.util.MOD_ID
import opekope2.avm_staff.api.staffsTag
import opekope2.avm_staff.util.contains
import opekope2.avm_staff.util.itemInStaff
import opekope2.avm_staff.util.staffHandler

@Suppress("unused")
object StaffMod : ModInitializer, IStaffMod {
override val staffItem: StaffItem = Registry.register(
Registries.ITEM,
Identifier(MOD_ID, "staff"),
FabricStaffItem(FabricItemSettings().maxCount(1))
)

override val isPhysicalClient: Boolean
get() = FabricLoader.getInstance().environmentType == EnvType.CLIENT

override val staffsTag: TagKey<Item> = TagKey.of(RegistryKeys.ITEM, Identifier(MOD_ID, "staffs"))

override val flamethrowerParticleType: DefaultParticleType = Registry.register(
Registries.PARTICLE_TYPE,
Identifier(MOD_ID, "flame"),
FabricParticleTypes.simple()
)

override val soulFlamethrowerParticleType: DefaultParticleType = Registry.register(
Registries.PARTICLE_TYPE,
Identifier(MOD_ID, "soul_fire_flame"),
FabricParticleTypes.simple()
)

object StaffMod : ModInitializer {
override fun onInitialize() {
AttackBlockCallback.EVENT.register(::attackBlock)
AttackEntityCallback.EVENT.register(::handleEntityAttackEvent)
}

@Suppress("UNUSED_PARAMETER")
private fun handleEntityAttackEvent(
player: PlayerEntity,
world: World,
hand: Hand,
target: Entity,
@Suppress("UNUSED_PARAMETER") hit: EntityHitResult?
hit: EntityHitResult?
): ActionResult {
if (world.isClient) return ActionResult.PASS // Handled with mixin
val itemStack = player.getStackInHand(hand)
if (itemStack !in staffsTag) return ActionResult.PASS

val itemInStaff = itemStack.itemInStaff ?: return ActionResult.PASS
val staffHandler = itemInStaff.staffHandler ?: return ActionResult.PASS

return attackEntity(player, world, hand, target)
val result = staffHandler.attackEntity(itemStack, world, player, target, hand)
return if (result.interruptsFurtherEvaluation()) ActionResult.SUCCESS
else ActionResult.PASS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,65 +21,22 @@ package opekope2.avm_staff.internal.fabric
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin
import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents
import net.minecraft.client.item.ModelPredicateProviderRegistry
import net.minecraft.client.render.model.UnbakedModel
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.item.ItemGroups
import net.minecraft.item.Items
import opekope2.avm_staff.IStaffMod
import opekope2.avm_staff.api.flamethrowerParticleType
import opekope2.avm_staff.api.particle.FlamethrowerParticle
import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING
import opekope2.avm_staff.internal.event_handler.handleKeyBindings
import opekope2.avm_staff.internal.fabric.item.model.UnbakedFabricStaffItemModel
import opekope2.avm_staff.internal.registerModelPredicateProviders
import opekope2.avm_staff.util.MOD_ID
import opekope2.avm_staff.api.soulFlamethrowerParticleType
import opekope2.avm_staff.internal.model.registerModelPredicateProviders

@Suppress("unused")
@Environment(EnvType.CLIENT)
object StaffModClient : ClientModInitializer {
override fun onInitializeClient() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.TOOLS).register { entries ->
entries.addAfter(Items.NETHERITE_HOE, StaffMod.staffItem)
ParticleFactoryRegistry.getInstance().apply {
register(flamethrowerParticleType.get(), FlamethrowerParticle::Factory)
register(soulFlamethrowerParticleType.get(), FlamethrowerParticle::Factory)
}
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register { entries ->
entries.addAfter(Items.TRIDENT, StaffMod.staffItem)
}

ModelLoadingPlugin.register(::modelLoadingPlugin)

KeyBindingHelper.registerKeyBinding(ADD_REMOVE_KEYBINDING)

ClientTickEvents.END_CLIENT_TICK.register(::handleKeyBindings)

ParticleFactoryRegistry.getInstance().register(
IStaffMod.get().flamethrowerParticleType,
FlamethrowerParticle::Factory
)
ParticleFactoryRegistry.getInstance().register(
IStaffMod.get().soulFlamethrowerParticleType,
FlamethrowerParticle::Factory
)

registerModelPredicateProviders(ModelPredicateProviderRegistry::register)
}

private fun modelLoadingPlugin(pluginContext: ModelLoadingPlugin.Context) {
pluginContext.modifyModelBeforeBake().register(::modifyModelBeforeBake)
}

private fun modifyModelBeforeBake(model: UnbakedModel, context: ModelModifier.BeforeBake.Context): UnbakedModel {
if (context.id().namespace != MOD_ID) return model

return when (context.id().path) {
// TODO hardcoded paths
"staff", "item/staff_in_use" -> UnbakedFabricStaffItemModel(model as JsonUnbakedModel) // FIXME
else -> model
}
}
}
Loading

0 comments on commit 5073b31

Please sign in to comment.