Skip to content
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

Staff Mod 0.13.0-beta #33

Merged
merged 7 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ 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
Expand Down Expand Up @@ -56,6 +58,18 @@ object StaffMod : ModInitializer, IStaffMod {

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()
)

override fun onInitialize() {
AttackBlockCallback.EVENT.register(::attackBlock)
AttackEntityCallback.EVENT.register(::handleEntityAttackEvent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ 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.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
Expand All @@ -54,6 +57,15 @@ object StaffModClient : ClientModInitializer {

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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import net.fabricmc.api.Environment
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.Baker
import net.minecraft.client.render.model.ModelBakeSettings
import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.client.texture.MissingSprite
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.Identifier
Expand All @@ -44,7 +44,7 @@ class UnbakedFabricStaffItemModel(private val original: JsonUnbakedModel) : Unba
return BakedFabricStaffItemModel(
original.bake(baker, textureGetter, rotationContainer, modelId) ?: return null,
itemModels,
baker.bake(MissingSprite.getMissingSpriteId(), rotationContainer)!!
baker.bake(ModelLoader.MISSING_ID, rotationContainer)!!
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package opekope2.avm_staff.internal.forge

import net.minecraft.item.Item
import net.minecraft.particle.DefaultParticleType
import net.minecraft.registry.tag.ItemTags
import net.minecraft.registry.tag.TagKey
import net.minecraft.util.Identifier
Expand All @@ -42,6 +43,16 @@ object StaffMod : IStaffMod {

private val STAFF_ITEM = ITEMS.register("staff") { ForgeStaffItem(Item.Settings().maxCount(1)) }

private val PARTICLE_TYPES = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, MOD_ID)

private val FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("flame") {
DefaultParticleType(false)
}

private val SOUL_FLAMETHROWER_PARTICLE_TYPE = PARTICLE_TYPES.register("soul_fire_flame") {
DefaultParticleType(false)
}

init {
initialize()
initializeNetworking()
Expand All @@ -57,7 +68,14 @@ object StaffMod : IStaffMod {

override val staffsTag: TagKey<Item> = ItemTags.create(Identifier(MOD_ID, "staffs"))

override val flamethrowerParticleType: DefaultParticleType
get() = FLAMETHROWER_PARTICLE_TYPE.get()

override val soulFlamethrowerParticleType: DefaultParticleType
get() = SOUL_FLAMETHROWER_PARTICLE_TYPE.get()

private fun initialize() {
ITEMS.register(MOD_BUS)
PARTICLE_TYPES.register(MOD_BUS)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ import net.minecraft.item.Items
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.api.distmarker.OnlyIn
import net.minecraftforge.client.event.RegisterKeyMappingsEvent
import net.minecraftforge.client.event.RegisterParticleProvidersEvent
import net.minecraftforge.common.MinecraftForge.EVENT_BUS
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent
import net.minecraftforge.event.TickEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import opekope2.avm_staff.IStaffMod
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.platform.forge.getStaffMod
Expand Down Expand Up @@ -69,6 +72,12 @@ object StaffModClient {
}
}

@SubscribeEvent
fun registerParticleProviders(event: RegisterParticleProvidersEvent) {
event.registerSpriteSet(IStaffMod.get().flamethrowerParticleType, FlamethrowerParticle::Factory)
event.registerSpriteSet(IStaffMod.get().soulFlamethrowerParticleType, FlamethrowerParticle::Factory)
}

@SubscribeEvent
fun registerKeyBindings(event: RegisterKeyMappingsEvent) {
event.register(ADD_REMOVE_KEYBINDING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ package opekope2.avm_staff.internal.forge.item.model
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.Baker
import net.minecraft.client.render.model.ModelBakeSettings
import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.client.texture.MissingSprite
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.Identifier
Expand All @@ -44,7 +44,7 @@ class UnbakedForgeStaffItemModel(private val original: JsonUnbakedModel) : Unbak
return BakedForgeStaffItemModel(
original.bake(baker, original, textureGetter, rotationContainer, modelId, true) ?: return null,
itemModels,
baker.bake(MissingSprite.getMissingSpriteId(), rotationContainer, textureGetter)!!
baker.bake(ModelLoader.MISSING_ID, rotationContainer, textureGetter)!!
)
}
}
30 changes: 30 additions & 0 deletions StaffMod/src/main/java/opekope2/avm_staff/mixin/IEntityMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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;

import net.minecraft.entity.Entity;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(Entity.class)
public interface IEntityMixin {
@Invoker
Vec3d invokeGetRotationVector(float pitch, float yaw);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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;

import net.minecraft.client.particle.Particle;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(Particle.class)
public interface IParticleMixin {
@Accessor
boolean isStopped();
}
20 changes: 20 additions & 0 deletions StaffMod/src/main/kotlin/opekope2/avm_staff/IStaffMod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

package opekope2.avm_staff

import net.minecraft.client.particle.ParticleManager
import net.minecraft.item.Item
import net.minecraft.particle.DefaultParticleType
import net.minecraft.registry.tag.TagKey
import opekope2.avm_staff.api.item.StaffItem
import opekope2.avm_staff.internal.platform.getStaffMod
Expand All @@ -44,6 +46,24 @@ interface IStaffMod {
*/
val staffsTag: TagKey<Item>

/**
* Gets the flamethrower's flame particle type.
*
* Due to how Forge registries work, *always* use this getter instead of storing the result.
*
* @see ParticleManager.addParticle
*/
val flamethrowerParticleType: DefaultParticleType

/**
* Gets the soul fire flamethrower's flame particle type.
*
* Due to how Forge registries work, *always* use this getter instead of storing the result.
*
* @see ParticleManager.addParticle
*/
val soulFlamethrowerParticleType: DefaultParticleType

companion object Holder {
/**
* Gets the currently running loader-specific Staff Mod instance.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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.api.particle

import net.minecraft.client.particle.*
import net.minecraft.client.world.ClientWorld
import net.minecraft.particle.DefaultParticleType
import net.minecraft.util.math.BlockPos
import opekope2.avm_staff.IStaffMod
import opekope2.avm_staff.mixin.IParticleMixin

/**
* Particle emitted by the campfire staff.
*
* @param world The world the particle is in
* @param x The X component of the particle's position
* @param y The Y component of the particle's position
* @param y The Z component of the particle's position
* @param velocityX The X component of the particle's velocity
* @param velocityY The Y component of the particle's velocity
* @param velocityZ The Z component of the particle's velocity
* @see FlamethrowerParticle.Factory
*/
class FlamethrowerParticle(
world: ClientWorld,
x: Double,
y: Double,
z: Double,
velocityX: Double,
velocityY: Double,
velocityZ: Double
) : AbstractSlowingParticle(world, x, y, z, velocityX, velocityY, velocityZ) {
private var stopped = 0

private val isSubmerged: Boolean
get() {
val blockPos = BlockPos.ofFloored(x, y, z)
val fluid = world.getFluidState(blockPos)
if (fluid.isEmpty) return false

val fluidShape = fluid.getShape(world, blockPos)

val rx = x - blockPos.x
val ry = y - blockPos.y
val rz = z - blockPos.z
// Check if source block, because the bounding box is shorter than 1 block, and some particles leak through
return fluid.isStill || fluidShape.boundingBoxes.any { it.contains(rx, ry, rz) }
}

init {
gravityStrength = 0f
velocityMultiplier = 1f

if (isSubmerged) {
markDead()
}
}

override fun getType(): ParticleTextureSheet = ParticleTextureSheet.PARTICLE_SHEET_OPAQUE

override fun move(dx: Double, dy: Double, dz: Double) {
val oldVX = velocityX
val oldVZ = velocityZ

super.move(dx, dy, dz)

if (isSubmerged) {
markDead()
return
}

@Suppress("CAST_NEVER_SUCCEEDS")
if ((this as IParticleMixin).isStopped || oldVX != velocityX || oldVZ != velocityZ) {
velocityX = 0.0
velocityY = 0.0
velocityZ = 0.0
stopped++
}

if (stopped == 1) {
maxAge -= (maxAge - age) / 2
stopped++
}
}

/**
* Factory class for [FlamethrowerParticle], intended to register in Minecraft instead of direct consumption.
*
* @param spriteProvider Flame sprite provider
* @see IStaffMod.flamethrowerParticleType
* @see ParticleManager.addParticle
*/
class Factory(private val spriteProvider: SpriteProvider) : ParticleFactory<DefaultParticleType> {
override fun createParticle(
parameters: DefaultParticleType,
world: ClientWorld,
x: Double,
y: Double,
z: Double,
velocityX: Double,
velocityY: Double,
velocityZ: Double
) = FlamethrowerParticle(world, x, y, z, velocityX, velocityY, velocityZ).apply {
setSprite(spriteProvider)
}
}
}
Loading
Loading