From 5fd1b9c309cc2f35c3295e5fed2f9ac81c6213da Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 12:49:27 +0100 Subject: [PATCH 1/9] Spiderman project setup --- ffa-server/build.gradle.kts | 1 + settings.gradle.kts | 1 + spiderman/build.gradle.kts | 18 ++++++ .../heroes/spiderman/SpidermanManager.kt | 33 +++++++++++ .../hero-api/textures/hero/spiderman/icon.png | Bin 0 -> 6920 bytes .../main/resources/assets/spiderman/icon.png | Bin 0 -> 6920 bytes .../assets/spiderman/lang/de_de.json | 3 + .../assets/spiderman/lang/en_us.json | 3 + spiderman/src/main/resources/fabric.mod.json | 54 ++++++++++++++++++ .../main/resources/spiderman.accesswidener | 1 + .../src/main/resources/spiderman.mixins.json | 13 +++++ 11 files changed, 127 insertions(+) create mode 100644 spiderman/build.gradle.kts create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt create mode 100644 spiderman/src/main/resources/assets/hero-api/textures/hero/spiderman/icon.png create mode 100644 spiderman/src/main/resources/assets/spiderman/icon.png create mode 100644 spiderman/src/main/resources/assets/spiderman/lang/de_de.json create mode 100644 spiderman/src/main/resources/assets/spiderman/lang/en_us.json create mode 100644 spiderman/src/main/resources/fabric.mod.json create mode 100644 spiderman/src/main/resources/spiderman.accesswidener create mode 100644 spiderman/src/main/resources/spiderman.mixins.json diff --git a/ffa-server/build.gradle.kts b/ffa-server/build.gradle.kts index e82b98f..742e0d9 100644 --- a/ffa-server/build.gradle.kts +++ b/ffa-server/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { api(project(":katara", configuration = "namedElements")) api(project(":aang", configuration = "namedElements")) api(project(":toph", configuration = "namedElements")) + api(project(":spiderman", configuration = "namedElements")) modApi(libs.bundles.fabric) modApi(libs.bundles.silk) diff --git a/settings.gradle.kts b/settings.gradle.kts index 26e904e..d18ad29 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,5 +17,6 @@ include(":hero-api") include(":katara") include(":aang") include(":toph") +include(":spiderman") include(":ffa-server") diff --git a/spiderman/build.gradle.kts b/spiderman/build.gradle.kts new file mode 100644 index 0000000..896b28c --- /dev/null +++ b/spiderman/build.gradle.kts @@ -0,0 +1,18 @@ +version = "1.0.0" + +dependencies { + implementation(project(":hero-api", configuration = "namedElements")) + implementation(project(":datatracker", configuration = "namedElements")) + + modApi(libs.bundles.fabric) + modApi(libs.bundles.silk) + modApi(libs.bundles.performance) + modApi(libs.owolib) + modApi(libs.geckolib) + modApi(libs.emoteLib) +} + +loom { + accessWidenerPath.set(file("src/main/resources/spiderman.accesswidener")) +} + diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt new file mode 100644 index 0000000..589c0c5 --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt @@ -0,0 +1,33 @@ +package gg.norisk.heroes.spiderman + +import gg.norisk.heroes.common.hero.Hero +import gg.norisk.heroes.common.hero.HeroManager.registerHero +import net.fabricmc.api.ClientModInitializer +import net.fabricmc.api.DedicatedServerModInitializer +import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents +import org.apache.logging.log4j.LogManager +import java.awt.Color + +object SpidermanManager : ModInitializer, ClientModInitializer, DedicatedServerModInitializer { + private const val MOD_ID = "spiderman" + val logger = LogManager.getLogger(MOD_ID) + + override fun onInitialize() { + logger.info("Starting $MOD_ID Hero...") + } + + override fun onInitializeClient() { + ClientLifecycleEvents.CLIENT_STARTED.register { + registerHero(Toph) + } + } + + override fun onInitializeServer() { + registerHero(Toph) + } + + val Toph by Hero("Spiderman") { + color = Color.RED.rgb + } +} diff --git a/spiderman/src/main/resources/assets/hero-api/textures/hero/spiderman/icon.png b/spiderman/src/main/resources/assets/hero-api/textures/hero/spiderman/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b903d12aaa5d6803e2ab0edc151020cefbf26e5 GIT binary patch literal 6920 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 C$Lp>D literal 0 HcmV?d00001 diff --git a/spiderman/src/main/resources/assets/spiderman/icon.png b/spiderman/src/main/resources/assets/spiderman/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b903d12aaa5d6803e2ab0edc151020cefbf26e5 GIT binary patch literal 6920 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 C$Lp>D literal 0 HcmV?d00001 diff --git a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json new file mode 100644 index 0000000..5c590fe --- /dev/null +++ b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json @@ -0,0 +1,3 @@ +{ + "text.hero.spiderman.description": "Spiderman Beschreibung???" +} diff --git a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json new file mode 100644 index 0000000..7a8801b --- /dev/null +++ b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "text.hero.spiderman.description": "Spiderman description???" +} diff --git a/spiderman/src/main/resources/fabric.mod.json b/spiderman/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..038641e --- /dev/null +++ b/spiderman/src/main/resources/fabric.mod.json @@ -0,0 +1,54 @@ +{ + "schemaVersion": 1, + "name": "Spiderman", + "id": "spiderman", + "version": "${version}", + "description": "Spiderman", + "authors": [ + "NoRiskk", + "Fabi.exe" + ], + "icon": "assets/spiderman/icon.png", + "license": "ARR", + "environment": "*", + "entrypoints": { + "main": [ + { + "adapter": "kotlin", + "value": "gg.norisk.heroes.spiderman.SpidermanManager" + } + ], + "client": [ + { + "adapter": "kotlin", + "value": "gg.norisk.heroes.spiderman.SpidermanManager" + } + ], + "server": [ + { + "adapter": "kotlin", + "value": "gg.norisk.heroes.spiderman.SpidermanManager" + } + ] + }, + "mixins": [ + "spiderman.mixins.json" + ], + "accessWidener": "spiderman.accesswidener", + "depends": { + "java": ">=21", + "minecraft": "*", + "fabric": "*", + "fabric-language-kotlin": "*" + }, + "custom": { + "modmenu": { + "badges": [ + "library" + ], + "parent": { + "id": "hero-api" + } + } + } +} diff --git a/spiderman/src/main/resources/spiderman.accesswidener b/spiderman/src/main/resources/spiderman.accesswidener new file mode 100644 index 0000000..d4342d0 --- /dev/null +++ b/spiderman/src/main/resources/spiderman.accesswidener @@ -0,0 +1 @@ +accessWidener v2 named diff --git a/spiderman/src/main/resources/spiderman.mixins.json b/spiderman/src/main/resources/spiderman.mixins.json new file mode 100644 index 0000000..0d48e16 --- /dev/null +++ b/spiderman/src/main/resources/spiderman.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "gg.norisk.heroes.spiderman.mixin", + "compatibilityLevel": "JAVA_21", + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + ], + "client": [ + ] +} From 4e17e033e28be51154089b450d9f57876b9e73c7 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 12:55:21 +0100 Subject: [PATCH 2/9] feat: add web swing ability --- .../heroes/spiderman/SpidermanManager.kt | 14 +++- .../spiderman/ability/WebShootAbility.kt | 71 ++++++++++++++++++ .../client/render/SwingWebRenderer.kt | 37 ++++++++++ .../heroes/spiderman/entity/SwingWebEntity.kt | 73 +++++++++++++++++++ .../spiderman/registry/EntityRegistry.kt | 29 ++++++++ .../registry/EntityRendererRegistry.kt | 10 +++ .../assets/spiderman/lang/de_de.json | 7 +- .../assets/spiderman/lang/en_us.json | 7 +- .../main/resources/spiderman.accesswidener | 4 + 9 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRegistry.kt create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRendererRegistry.kt diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt index 589c0c5..b36972f 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt @@ -2,32 +2,40 @@ package gg.norisk.heroes.spiderman import gg.norisk.heroes.common.hero.Hero import gg.norisk.heroes.common.hero.HeroManager.registerHero +import gg.norisk.heroes.spiderman.ability.WebShootAbility +import gg.norisk.heroes.spiderman.registry.EntityRegistry +import gg.norisk.heroes.spiderman.registry.EntityRendererRegistry import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.DedicatedServerModInitializer import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents +import net.minecraft.util.Identifier import org.apache.logging.log4j.LogManager import java.awt.Color object SpidermanManager : ModInitializer, ClientModInitializer, DedicatedServerModInitializer { private const val MOD_ID = "spiderman" val logger = LogManager.getLogger(MOD_ID) + fun String.toId() = Identifier.of(MOD_ID, this) override fun onInitialize() { logger.info("Starting $MOD_ID Hero...") + EntityRegistry.init() } override fun onInitializeClient() { ClientLifecycleEvents.CLIENT_STARTED.register { - registerHero(Toph) + registerHero(Spiderman) } + EntityRendererRegistry.init() } override fun onInitializeServer() { - registerHero(Toph) + registerHero(Spiderman) } - val Toph by Hero("Spiderman") { + val Spiderman by Hero("Spiderman") { color = Color.RED.rgb + ability(WebShootAbility) } } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt new file mode 100644 index 0000000..fe5e38b --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt @@ -0,0 +1,71 @@ +package gg.norisk.heroes.spiderman.ability + +import gg.norisk.heroes.client.option.HeroKeyBindings +import gg.norisk.heroes.common.HeroesManager.client +import gg.norisk.heroes.common.ability.NumberProperty +import gg.norisk.heroes.common.ability.operation.AddValueTotal +import gg.norisk.heroes.common.hero.ability.AbilityScope +import gg.norisk.heroes.common.hero.ability.implementation.PressAbility +import gg.norisk.heroes.spiderman.entity.SwingWebEntity +import gg.norisk.heroes.spiderman.registry.EntityRegistry +import io.wispforest.owo.ui.component.Components +import io.wispforest.owo.ui.core.Component +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Items +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.Identifier +import net.minecraft.util.TypeFilter +import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.entity.directionVector +import net.silkmc.silk.core.item.itemStack + +val ropeLength = NumberProperty(50.0, 3, "Rope length", AddValueTotal(5.0, 10.0, 15.0, 20.0), 10).apply { + icon = { + Components.item(Items.FIREWORK_ROCKET.defaultStack) + } +} + +val webShootPower = NumberProperty(1.0, 3, "Web shoot power", AddValueTotal(1.4, 1.9, 2.5), 20).apply { + icon = { + Components.item(Items.FIREWORK_ROCKET.defaultStack) + } +} + +@OptIn(ExperimentalSilkApi::class) +object WebShootAbility : PressAbility("Web Shoot") { + init { + client { + keyBind = HeroKeyBindings.firstKeyBind + } + properties = listOf(ropeLength, webShootPower) + cooldownProperty = buildCooldown(60.0, 5, AddValueTotal(-10.0, -5.0, -5.0, -5.0, -10.0)) + } + + override fun getIconComponent(): Component { + return Components.item(itemStack(Items.STRING) {}) + } + + override fun getBackgroundTexture(): Identifier { + return Identifier.of("textures/block/packed_mud.png") + } + + override fun onStart(player: PlayerEntity, abilityScope: AbilityScope) { + if (player.world is ServerWorld) { + val web = SwingWebEntity(EntityRegistry.SWING_WEB, player.world) + web.setPosition(player.eyePos) + web.owner = player + web.velocity = player.directionVector.multiply(webShootPower.getValue(player.uuid)) + web.ropeLength = ropeLength.getValue(player.uuid) + player.world.spawnEntity(web) + } + } + + override fun onDisable(player: PlayerEntity) { + val world = player.world as ServerWorld + for (entity in world.getEntitiesByType(TypeFilter.instanceOf(SwingWebEntity::class.java)) { true }) { + if (entity.owner == player) { + entity.discard() + } + } + } +} diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt new file mode 100644 index 0000000..c176e11 --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt @@ -0,0 +1,37 @@ +package gg.norisk.heroes.spiderman.client.render + +import gg.norisk.heroes.spiderman.entity.SwingWebEntity +import net.minecraft.client.render.OverlayTexture +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.entity.EntityRenderer +import net.minecraft.client.render.entity.EntityRendererFactory +import net.minecraft.client.render.entity.state.ProjectileEntityRenderState +import net.minecraft.client.render.item.ItemRenderState +import net.minecraft.client.util.math.MatrixStack + +class SwingWebRenderer(context: EntityRendererFactory.Context) : + EntityRenderer(context) { + private val itemRenderState = ItemRenderState() + + override fun createRenderState(): ProjectileEntityRenderState? { + return ProjectileEntityRenderState() + } + + override fun render( + state: ProjectileEntityRenderState?, + matrixStack: MatrixStack, + vertexConsumerProvider: VertexConsumerProvider?, + light: Int + ) { + matrixStack.push() + matrixStack.multiply(dispatcher.rotation) + ItemRenderState().render( + matrixStack, + vertexConsumerProvider, + light, + OverlayTexture.DEFAULT_UV + ) + matrixStack.pop() + super.render(state, matrixStack, vertexConsumerProvider, light) + } +} \ No newline at end of file diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt new file mode 100644 index 0000000..033708a --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt @@ -0,0 +1,73 @@ +package gg.norisk.heroes.spiderman.entity + +import gg.norisk.datatracker.entity.getSyncedData +import gg.norisk.datatracker.entity.setSyncedData +import net.minecraft.client.network.ClientPlayerEntity +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityType +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.projectile.PersistentProjectileEntity +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.TypeFilter +import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.hit.EntityHitResult +import net.minecraft.world.World +import kotlin.math.abs + +class SwingWebEntity(entityType: EntityType, world: World) : PersistentProjectileEntity(entityType, world) { + var ropeLength: Double + get() = this.getSyncedData("RopeLength") ?: 0.0 + set(value) = this.setSyncedData("RopeLength", value) + var currentLength = -1.0 + + override fun getDefaultItemStack(): ItemStack? = ItemStack(Items.COBWEB) + + override fun tick() { + super.tick() + + val player = owner as? PlayerEntity? ?: return + val distance = distanceTo(player) + if (player.isDead || distance > ropeLength || player.isSneaking) { + discard() + } + + if (isInGround && distance > currentLength) { + if (world.isClient && player is ClientPlayerEntity) { + if (player.input.playerInput.jump) { + val vec = player.pos.subtract(player.pos).multiply(0.5) + player.addVelocity(vec.horizontal) + } + } + val vec = pos.subtract(player.pos).multiply(0.05) + player.addVelocity(vec.multiply(abs(vec.x) * 2, 1.0, abs(vec.z) * 2)) + } + } + + private fun onHit() { + if (owner == null) { + return + } + currentLength = distanceTo(owner).toDouble() * 0.85 + if (!world.isClient) { + for (entity in (world as ServerWorld).getEntitiesByType(TypeFilter.instanceOf(SwingWebEntity::class.java)) { true }) { + if (entity.owner == owner && entity != this) { + entity.discard() + } + } + } + owner?.addVelocity(pos.subtract(owner?.pos).multiply(0.1, 0.001, 0.1)) + } + + override fun onEntityHit(entityHitResult: EntityHitResult?) = onHit() + + override fun onBlockHit(blockHitResult: BlockHitResult?) { + super.onBlockHit(blockHitResult) + onHit() + } + + override fun getGravity(): Double = 0.01 + + override fun canHit(entity: Entity?): Boolean = entity != owner +} diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRegistry.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRegistry.kt new file mode 100644 index 0000000..5f83971 --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRegistry.kt @@ -0,0 +1,29 @@ +package gg.norisk.heroes.spiderman.registry + +import gg.norisk.heroes.common.HeroesManager +import gg.norisk.heroes.spiderman.SpidermanManager.toId +import gg.norisk.heroes.spiderman.entity.SwingWebEntity +import net.minecraft.entity.EntityType +import net.minecraft.entity.SpawnGroup +import net.minecraft.registry.Registries +import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys + +object EntityRegistry { + val SWING_WEB = Registry.register( + Registries.ENTITY_TYPE, + "swing_web".toId(), + EntityType.Builder.create(::SwingWebEntity, SpawnGroup.MISC) + .requires(HeroesManager.heroesFlag) + .dimensions(0.3125f, 0.3125f) + .build(keyOf("swing_web")) + ) + + fun init() { + } + + private fun keyOf(id: String): RegistryKey> { + return RegistryKey.of(RegistryKeys.ENTITY_TYPE, id.toId()) + } +} diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRendererRegistry.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRendererRegistry.kt new file mode 100644 index 0000000..ed4208a --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/registry/EntityRendererRegistry.kt @@ -0,0 +1,10 @@ +package gg.norisk.heroes.spiderman.registry + +import gg.norisk.heroes.spiderman.client.render.SwingWebRenderer +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry + +object EntityRendererRegistry { + fun init() { + EntityRendererRegistry.register(EntityRegistry.SWING_WEB, ::SwingWebRenderer) + } +} diff --git a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json index 5c590fe..cdee5a2 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json @@ -1,3 +1,8 @@ { - "text.hero.spiderman.description": "Spiderman Beschreibung???" + "text.hero.spiderman.description": "Spiderman Beschreibung???", + "hero.spiderman.ability.web_shoot.description": "Scheiße ein Netz und schwinge.", + "heroes.property.web_shoot_power": "Schusskraft", + "heroes.property.web_shoot_power.description": "Die Kraft, mit der zu das Netz schießt.", + "heroes.property.rope_length": "Netzlänge", + "heroes.property.rope_length.description": "Die Länge deines Netzes." } diff --git a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json index 7a8801b..d2c336f 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json @@ -1,3 +1,8 @@ { - "text.hero.spiderman.description": "Spiderman description???" + "text.hero.spiderman.description": "Spiderman description???", + "hero.spiderman.ability.web_shoot.description": "Shoot a web and swing.", + "heroes.property.web_shoot_power": "Web shoot power", + "heroes.property.web_shoot_power.description": "The shooting power.", + "heroes.property.rope_length": "Web rope length", + "heroes.property.rope_length.description": "The length of your web rope." } diff --git a/spiderman/src/main/resources/spiderman.accesswidener b/spiderman/src/main/resources/spiderman.accesswidener index d4342d0..ec85d5a 100644 --- a/spiderman/src/main/resources/spiderman.accesswidener +++ b/spiderman/src/main/resources/spiderman.accesswidener @@ -1 +1,5 @@ accessWidener v2 named +accessible class net/minecraft/client/gui/hud/InGameHud$HeartType +accessible field net/minecraft/entity/FallingBlockEntity block Lnet/minecraft/block/BlockState; +accessible class net/minecraft/client/render/BackgroundRenderer$DarknessFogModifier +accessible class net/minecraft/client/render/BackgroundRenderer$FogData From 5721b8be6b443156d1ec95c0577e73a3319bdfb3 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 14:21:51 +0100 Subject: [PATCH 3/9] fix: disable swing web pickup --- .../gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt index 033708a..0357ee7 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/SwingWebEntity.kt @@ -60,14 +60,16 @@ class SwingWebEntity(entityType: EntityType, world: World) : Per owner?.addVelocity(pos.subtract(owner?.pos).multiply(0.1, 0.001, 0.1)) } - override fun onEntityHit(entityHitResult: EntityHitResult?) = onHit() + override fun onEntityHit(entityHitResult: EntityHitResult) = onHit() - override fun onBlockHit(blockHitResult: BlockHitResult?) { + override fun onBlockHit(blockHitResult: BlockHitResult) { super.onBlockHit(blockHitResult) onHit() } override fun getGravity(): Double = 0.01 - override fun canHit(entity: Entity?): Boolean = entity != owner + override fun canHit(entity: Entity): Boolean = entity != owner + + override fun tryPickup(player: PlayerEntity): Boolean = false } From 21280cdfbc482cc7f61254f48579a55d3898af77 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 14:36:04 +0100 Subject: [PATCH 4/9] feat: swing web rendering --- .../client/render/SwingWebRenderer.kt | 152 +++++++++++++++--- 1 file changed, 134 insertions(+), 18 deletions(-) diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt index c176e11..5d9c2ea 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/client/render/SwingWebRenderer.kt @@ -1,37 +1,153 @@ package gg.norisk.heroes.spiderman.client.render import gg.norisk.heroes.spiderman.entity.SwingWebEntity -import net.minecraft.client.render.OverlayTexture -import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.* import net.minecraft.client.render.entity.EntityRenderer import net.minecraft.client.render.entity.EntityRendererFactory -import net.minecraft.client.render.entity.state.ProjectileEntityRenderState +import net.minecraft.client.render.entity.state.EntityRenderState +import net.minecraft.client.render.entity.state.EntityRenderState.LeashData import net.minecraft.client.render.item.ItemRenderState import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.item.ModelTransformationMode +import net.minecraft.util.math.MathHelper +import org.joml.Matrix4f + +private val webItemStack = ItemStack(Items.COBWEB) + +class SwingWebRenderState : EntityRenderState() { + val itemRenderState = ItemRenderState() +} class SwingWebRenderer(context: EntityRendererFactory.Context) : - EntityRenderer(context) { - private val itemRenderState = ItemRenderState() + EntityRenderer(context) { + private val itemModelManager = context.itemModelManager + + override fun createRenderState(): SwingWebRenderState? { + return SwingWebRenderState() + } - override fun createRenderState(): ProjectileEntityRenderState? { - return ProjectileEntityRenderState() + override fun updateRenderState(entity: SwingWebEntity, state: SwingWebRenderState, tickDelta: Float) { + super.updateRenderState(entity, state, tickDelta) + itemModelManager.updateForNonLivingEntity( + state.itemRenderState, + webItemStack, + ModelTransformationMode.GROUND, + entity) + if (state.leashData == null) { + state.leashData = LeashData() + } + state.leashData!!.startPos = entity.pos + val owner = entity.owner + state.leashData!!.endPos = if (owner != null) owner.pos.add(0.0, owner.height / 2.0, 0.0) else entity.pos } - override fun render( - state: ProjectileEntityRenderState?, - matrixStack: MatrixStack, - vertexConsumerProvider: VertexConsumerProvider?, - light: Int - ) { + override fun render(state: SwingWebRenderState, + matrixStack: MatrixStack, + vertexConsumerProvider: VertexConsumerProvider, + light: Int) { matrixStack.push() matrixStack.multiply(dispatcher.rotation) - ItemRenderState().render( + matrixStack.scale(4f, 4f, 4f) + state.itemRenderState.render( matrixStack, vertexConsumerProvider, light, - OverlayTexture.DEFAULT_UV - ) + OverlayTexture.DEFAULT_UV) matrixStack.pop() - super.render(state, matrixStack, vertexConsumerProvider, light) + + val leashData = state.leashData + if (leashData != null) { + renderLeash(matrixStack, vertexConsumerProvider, leashData) + } + } + + // net.minecraft.client.render.entity.EntityRenderer.renderLeash + private fun renderLeash(matrices: MatrixStack, vertexConsumers: VertexConsumerProvider, leashData: LeashData) { + val g = (leashData.endPos.x - leashData.startPos.x).toFloat() + val h = (leashData.endPos.y - leashData.startPos.y).toFloat() + val i = (leashData.endPos.z - leashData.startPos.z).toFloat() + val j = MathHelper.inverseSqrt(g * g + i * i) * 0.025f / 2.0f + val k = i * j + val l = g * j + matrices.push() + matrices.translate(leashData.offset) + val vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getLeash()) + val matrix4f = matrices.peek().getPositionMatrix() + + for (m in 0..24) { + renderLeashSegment( + vertexConsumer, + matrix4f, + g, + h, + i, + leashData.leashedEntityBlockLight, + leashData.leashHolderBlockLight, + leashData.leashedEntitySkyLight, + leashData.leashHolderSkyLight, + 0.025f, + 0.025f, + k, + l, + m, + false) + } + + for (m in 24 downTo 0) { + renderLeashSegment( + vertexConsumer, + matrix4f, + g, + h, + i, + leashData.leashedEntityBlockLight, + leashData.leashHolderBlockLight, + leashData.leashedEntitySkyLight, + leashData.leashHolderSkyLight, + 0.025f, + 0.0f, + k, + l, + m, + true) + } + + matrices.pop() + } + + // net.minecraft.client.render.entity.EntityRenderer.renderLeashSegment + private fun renderLeashSegment(vertexConsumer: VertexConsumer, + matrix: Matrix4f, + leashedEntityX: Float, + leashedEntityY: Float, + leashedEntityZ: Float, + leashedEntityBlockLight: Int, + leashHolderBlockLight: Int, + leashedEntitySkyLight: Int, + leashHolderSkyLight: Int, + f: Float, + g: Float, + h: Float, + i: Float, + segmentIndex: Int, + isLeashKnot: Boolean) { + val j = segmentIndex.toFloat() / 24.0f + val k = MathHelper.lerp(j, leashedEntityBlockLight.toFloat(), leashHolderBlockLight.toFloat()).toInt() + val l = MathHelper.lerp(j, leashedEntitySkyLight.toFloat(), leashHolderSkyLight.toFloat()).toInt() + val m = LightmapTextureManager.pack(k, l) + val n = if (segmentIndex % 2 == (if (isLeashKnot) 1 else 0)) 0.7f else 1.0f + val o = 0.75f * n + val p = 0.75f * n + val q = 0.75f * n + val r = leashedEntityX * j + val s = if (leashedEntityY > 0.0f) + leashedEntityY * j * j + else + leashedEntityY - leashedEntityY * (1.0f - j) * (1.0f - j) + val t = leashedEntityZ * j + vertexConsumer.vertex(matrix, r - h * 6, s + g, t + i * 6).color(o, p, q, 1.0f).light(m) + vertexConsumer.vertex(matrix, r + h * 6, s + f - g, t - i * 6).color(o, p, q, 1.0f).light(m) } -} \ No newline at end of file +} From c1a7fb022fa142d79be1fc15fe2c44ff934b6727 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 14:38:50 +0100 Subject: [PATCH 5/9] refactor: rename WebShootAbility to SwingAbility --- .../kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt | 4 ++-- .../spiderman/ability/{WebShootAbility.kt => SwingAbility.kt} | 2 +- spiderman/src/main/resources/assets/spiderman/lang/de_de.json | 2 +- spiderman/src/main/resources/assets/spiderman/lang/en_us.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/{WebShootAbility.kt => SwingAbility.kt} (98%) diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt index b36972f..bace48e 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt @@ -2,7 +2,7 @@ package gg.norisk.heroes.spiderman import gg.norisk.heroes.common.hero.Hero import gg.norisk.heroes.common.hero.HeroManager.registerHero -import gg.norisk.heroes.spiderman.ability.WebShootAbility +import gg.norisk.heroes.spiderman.ability.SwingAbility import gg.norisk.heroes.spiderman.registry.EntityRegistry import gg.norisk.heroes.spiderman.registry.EntityRendererRegistry import net.fabricmc.api.ClientModInitializer @@ -36,6 +36,6 @@ object SpidermanManager : ModInitializer, ClientModInitializer, DedicatedServerM val Spiderman by Hero("Spiderman") { color = Color.RED.rgb - ability(WebShootAbility) + ability(SwingAbility) } } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/SwingAbility.kt similarity index 98% rename from spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt rename to spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/SwingAbility.kt index fe5e38b..972d521 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WebShootAbility.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/SwingAbility.kt @@ -32,7 +32,7 @@ val webShootPower = NumberProperty(1.0, 3, "Web shoot power", AddValueTotal(1.4, } @OptIn(ExperimentalSilkApi::class) -object WebShootAbility : PressAbility("Web Shoot") { +object SwingAbility : PressAbility("Swing") { init { client { keyBind = HeroKeyBindings.firstKeyBind diff --git a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json index cdee5a2..04d0196 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json @@ -1,6 +1,6 @@ { "text.hero.spiderman.description": "Spiderman Beschreibung???", - "hero.spiderman.ability.web_shoot.description": "Scheiße ein Netz und schwinge.", + "hero.spiderman.ability.swing.description": "Scheiße ein Netz und schwinge.", "heroes.property.web_shoot_power": "Schusskraft", "heroes.property.web_shoot_power.description": "Die Kraft, mit der zu das Netz schießt.", "heroes.property.rope_length": "Netzlänge", diff --git a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json index d2c336f..6e6bd31 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json @@ -1,6 +1,6 @@ { "text.hero.spiderman.description": "Spiderman description???", - "hero.spiderman.ability.web_shoot.description": "Shoot a web and swing.", + "hero.spiderman.ability.swing.description": "Shoot a web and swing.", "heroes.property.web_shoot_power": "Web shoot power", "heroes.property.web_shoot_power.description": "The shooting power.", "heroes.property.rope_length": "Web rope length", From 8076f002d13efd904c65d5b6526280f1a321f0a6 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Wed, 12 Mar 2025 15:25:52 +0100 Subject: [PATCH 6/9] feat: add throw webs ability --- .../heroes/spiderman/SpidermanManager.kt | 2 + .../spiderman/ability/ThrowWebsAbility.kt | 57 +++++++++++++++++++ .../assets/spiderman/lang/de_de.json | 4 +- .../assets/spiderman/lang/en_us.json | 4 +- .../main/resources/spiderman.accesswidener | 4 -- 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt index bace48e..1410eee 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/SpidermanManager.kt @@ -3,6 +3,7 @@ package gg.norisk.heroes.spiderman import gg.norisk.heroes.common.hero.Hero import gg.norisk.heroes.common.hero.HeroManager.registerHero import gg.norisk.heroes.spiderman.ability.SwingAbility +import gg.norisk.heroes.spiderman.ability.ThrowWebsAbility import gg.norisk.heroes.spiderman.registry.EntityRegistry import gg.norisk.heroes.spiderman.registry.EntityRendererRegistry import net.fabricmc.api.ClientModInitializer @@ -37,5 +38,6 @@ object SpidermanManager : ModInitializer, ClientModInitializer, DedicatedServerM val Spiderman by Hero("Spiderman") { color = Color.RED.rgb ability(SwingAbility) + ability(ThrowWebsAbility) } } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt new file mode 100644 index 0000000..8ff39cc --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt @@ -0,0 +1,57 @@ +package gg.norisk.heroes.spiderman.ability + +import gg.norisk.heroes.client.option.HeroKeyBindings +import gg.norisk.heroes.common.HeroesManager.client +import gg.norisk.heroes.common.ability.NumberProperty +import gg.norisk.heroes.common.ability.operation.AddValueTotal +import gg.norisk.heroes.common.hero.ability.AbilityScope +import gg.norisk.heroes.common.hero.ability.implementation.PressAbility +import io.wispforest.owo.ui.component.Components +import io.wispforest.owo.ui.core.Component +import net.minecraft.block.Blocks +import net.minecraft.entity.EntityType +import net.minecraft.entity.FallingBlockEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Items +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.Identifier +import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.entity.directionVector +import net.silkmc.silk.core.item.itemStack + +val webAmount = NumberProperty(1.0, 4, "Web amount", AddValueTotal(1.0, 1.0, 2.0, 2.0)).apply { + icon = { + Components.item(Items.COBWEB.defaultStack) + } +} + +@OptIn(ExperimentalSilkApi::class) +object ThrowWebsAbility : PressAbility("Throw webs") { + init { + client { + keyBind = HeroKeyBindings.secondKeyBind + } + properties = listOf(webAmount) + cooldownProperty = buildCooldown(90.0, 5, AddValueTotal(-9.0, -9.0, -9.0, -9.0, -9.0)) + } + + override fun getIconComponent(): Component { + return Components.item(itemStack(Items.COBWEB) {}) + } + + override fun getBackgroundTexture(): Identifier { + return Identifier.of("textures/block/packed_mud.png") + } + + override fun onStart(player: PlayerEntity, abilityScope: AbilityScope) { + if (player.world is ServerWorld) { + repeat(webAmount.getValue(player.uuid).toInt()) { + val web = FallingBlockEntity(EntityType.FALLING_BLOCK, player.world) + web.setPosition(player.eyePos) + web.block = Blocks.COBWEB.defaultState + web.velocity = player.directionVector.multiply(0.6).addRandom(player.world.random, 0.3f) + player.world.spawnEntity(web) + } + } + } +} diff --git a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json index 04d0196..1aecd34 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/de_de.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/de_de.json @@ -4,5 +4,7 @@ "heroes.property.web_shoot_power": "Schusskraft", "heroes.property.web_shoot_power.description": "Die Kraft, mit der zu das Netz schießt.", "heroes.property.rope_length": "Netzlänge", - "heroes.property.rope_length.description": "Die Länge deines Netzes." + "heroes.property.rope_length.description": "Die Länge deines Netzes.", + "hero.spiderman.ability.throw_webs.description": "Werfe Spinnennetze.", + "heroes.property.web_amount": "Menge" } diff --git a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json index 6e6bd31..fd6484f 100644 --- a/spiderman/src/main/resources/assets/spiderman/lang/en_us.json +++ b/spiderman/src/main/resources/assets/spiderman/lang/en_us.json @@ -4,5 +4,7 @@ "heroes.property.web_shoot_power": "Web shoot power", "heroes.property.web_shoot_power.description": "The shooting power.", "heroes.property.rope_length": "Web rope length", - "heroes.property.rope_length.description": "The length of your web rope." + "heroes.property.rope_length.description": "The length of your web rope.", + "hero.spiderman.ability.throw_webs.description": "Throw cobwebs.", + "heroes.property.web_amount": "Amount" } diff --git a/spiderman/src/main/resources/spiderman.accesswidener b/spiderman/src/main/resources/spiderman.accesswidener index ec85d5a..d4342d0 100644 --- a/spiderman/src/main/resources/spiderman.accesswidener +++ b/spiderman/src/main/resources/spiderman.accesswidener @@ -1,5 +1 @@ accessWidener v2 named -accessible class net/minecraft/client/gui/hud/InGameHud$HeartType -accessible field net/minecraft/entity/FallingBlockEntity block Lnet/minecraft/block/BlockState; -accessible class net/minecraft/client/render/BackgroundRenderer$DarknessFogModifier -accessible class net/minecraft/client/render/BackgroundRenderer$FogData From 13e7edd13c5afdc90ef8a1c7141dc7af7aba82c3 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Sat, 22 Mar 2025 00:54:17 +0100 Subject: [PATCH 7/9] feat: wall climb ability --- .../spiderman/mixin/PlayerEntityMixin.java | 16 ++++++++++++++++ .../heroes/spiderman/ability/ThrowWebsAbility.kt | 4 +--- .../heroes/spiderman/ability/WallClimbAbility.kt | 12 ++++++++++++ .../src/main/resources/spiderman.accesswidener | 1 + .../src/main/resources/spiderman.mixins.json | 1 + 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt diff --git a/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java new file mode 100644 index 0000000..c6dcb5c --- /dev/null +++ b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java @@ -0,0 +1,16 @@ +package gg.norisk.heroes.spiderman.mixin; + +import gg.norisk.heroes.spiderman.ability.WallClimbAbilityKt; +import net.minecraft.entity.player.PlayerEntity; +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(PlayerEntity.class) +public class PlayerEntityMixin { + @Inject(method = "isClimbing", at = @At("RETURN"), cancellable = true) + private void isClimbing(CallbackInfoReturnable cir) { + WallClimbAbilityKt.handleClimbCheck((PlayerEntity) (Object) this, cir); + } +} diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt index 8ff39cc..c128470 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt @@ -46,9 +46,7 @@ object ThrowWebsAbility : PressAbility("Throw webs") { override fun onStart(player: PlayerEntity, abilityScope: AbilityScope) { if (player.world is ServerWorld) { repeat(webAmount.getValue(player.uuid).toInt()) { - val web = FallingBlockEntity(EntityType.FALLING_BLOCK, player.world) - web.setPosition(player.eyePos) - web.block = Blocks.COBWEB.defaultState + val web = FallingBlockEntity(player.world, player.x, player.eyePos.y, player.z, Blocks.COBWEB.defaultState) web.velocity = player.directionVector.multiply(0.6).addRandom(player.world.random, 0.3f) player.world.spawnEntity(web) } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt new file mode 100644 index 0000000..b3e54f7 --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt @@ -0,0 +1,12 @@ +package gg.norisk.heroes.spiderman.ability + +import gg.norisk.heroes.common.hero.getHero +import gg.norisk.heroes.spiderman.SpidermanManager +import net.minecraft.entity.player.PlayerEntity +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable + +fun handleClimbCheck(player: PlayerEntity, cir: CallbackInfoReturnable) { + if (player.getHero() == SpidermanManager.Spiderman && !player.isSpectator && player.horizontalCollision) { + cir.returnValue = true + } +} diff --git a/spiderman/src/main/resources/spiderman.accesswidener b/spiderman/src/main/resources/spiderman.accesswidener index d4342d0..6dce5c4 100644 --- a/spiderman/src/main/resources/spiderman.accesswidener +++ b/spiderman/src/main/resources/spiderman.accesswidener @@ -1 +1,2 @@ accessWidener v2 named +accessible method net/minecraft/entity/FallingBlockEntity (Lnet/minecraft/world/World;DDDLnet/minecraft/block/BlockState;)V diff --git a/spiderman/src/main/resources/spiderman.mixins.json b/spiderman/src/main/resources/spiderman.mixins.json index 0d48e16..d949029 100644 --- a/spiderman/src/main/resources/spiderman.mixins.json +++ b/spiderman/src/main/resources/spiderman.mixins.json @@ -7,6 +7,7 @@ "defaultRequire": 1 }, "mixins": [ + "PlayerEntityMixin" ], "client": [ ] From 9591d339120adc798cc6a14dcdd306efd199eef3 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Sat, 22 Mar 2025 12:02:43 +0100 Subject: [PATCH 8/9] feat: cobweb climb ability --- .../spiderman/mixin/CobwebBlockMixin.java | 23 +++++++++++++++++++ .../spiderman/mixin/PlayerEntityMixin.java | 5 +++- .../spiderman/ability/CobwebClimbAbility.kt | 20 ++++++++++++++++ .../spiderman/ability/ThrowWebsAbility.kt | 6 ++--- .../spiderman/ability/WallClimbAbility.kt | 2 +- .../spiderman/entity/FallingCobwebEntity.kt | 8 +++++++ .../src/main/resources/spiderman.mixins.json | 1 + 7 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/CobwebBlockMixin.java create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/CobwebClimbAbility.kt create mode 100644 spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt diff --git a/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/CobwebBlockMixin.java b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/CobwebBlockMixin.java new file mode 100644 index 0000000..2ec9de5 --- /dev/null +++ b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/CobwebBlockMixin.java @@ -0,0 +1,23 @@ +package gg.norisk.heroes.spiderman.mixin; + +import gg.norisk.heroes.spiderman.ability.CobwebClimbAbilityKt; +import net.minecraft.block.BlockState; +import net.minecraft.block.CobwebBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +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.CallbackInfo; + +@Mixin(CobwebBlock.class) +public class CobwebBlockMixin { + @Inject(method = "onEntityCollision", at = @At("HEAD"), cancellable = true) + public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity, CallbackInfo ci) { + if (entity instanceof PlayerEntity player) { + CobwebClimbAbilityKt.handleCobwebCollision(player, ci); + } + } +} diff --git a/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java index c6dcb5c..ee4fec0 100644 --- a/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java +++ b/spiderman/src/main/java/gg/norisk/heroes/spiderman/mixin/PlayerEntityMixin.java @@ -1,5 +1,6 @@ package gg.norisk.heroes.spiderman.mixin; +import gg.norisk.heroes.spiderman.ability.CobwebClimbAbilityKt; import gg.norisk.heroes.spiderman.ability.WallClimbAbilityKt; import net.minecraft.entity.player.PlayerEntity; import org.spongepowered.asm.mixin.Mixin; @@ -11,6 +12,8 @@ public class PlayerEntityMixin { @Inject(method = "isClimbing", at = @At("RETURN"), cancellable = true) private void isClimbing(CallbackInfoReturnable cir) { - WallClimbAbilityKt.handleClimbCheck((PlayerEntity) (Object) this, cir); + PlayerEntity self = (PlayerEntity) (Object) this; + WallClimbAbilityKt.handleWallClimbCheck(self, cir); + CobwebClimbAbilityKt.handleCobwebClimbCheck(self, cir); } } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/CobwebClimbAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/CobwebClimbAbility.kt new file mode 100644 index 0000000..99e48f7 --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/CobwebClimbAbility.kt @@ -0,0 +1,20 @@ +package gg.norisk.heroes.spiderman.ability + +import gg.norisk.heroes.common.hero.getHero +import gg.norisk.heroes.spiderman.SpidermanManager +import net.minecraft.block.Blocks +import net.minecraft.entity.player.PlayerEntity +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable + +fun handleCobwebCollision(player: PlayerEntity, ci: CallbackInfo) { + if (player.getHero() == SpidermanManager.Spiderman && !player.isSpectator) { + ci.cancel() + } +} + +fun handleCobwebClimbCheck(player: PlayerEntity, cir: CallbackInfoReturnable) { + if (player.getHero() == SpidermanManager.Spiderman && !player.isSpectator && player.blockStateAtPos.block == Blocks.COBWEB) { + cir.returnValue = true + } +} diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt index c128470..0d7da5c 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/ThrowWebsAbility.kt @@ -6,11 +6,9 @@ import gg.norisk.heroes.common.ability.NumberProperty import gg.norisk.heroes.common.ability.operation.AddValueTotal import gg.norisk.heroes.common.hero.ability.AbilityScope import gg.norisk.heroes.common.hero.ability.implementation.PressAbility +import gg.norisk.heroes.spiderman.entity.FallingCobwebEntity import io.wispforest.owo.ui.component.Components import io.wispforest.owo.ui.core.Component -import net.minecraft.block.Blocks -import net.minecraft.entity.EntityType -import net.minecraft.entity.FallingBlockEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Items import net.minecraft.server.world.ServerWorld @@ -46,7 +44,7 @@ object ThrowWebsAbility : PressAbility("Throw webs") { override fun onStart(player: PlayerEntity, abilityScope: AbilityScope) { if (player.world is ServerWorld) { repeat(webAmount.getValue(player.uuid).toInt()) { - val web = FallingBlockEntity(player.world, player.x, player.eyePos.y, player.z, Blocks.COBWEB.defaultState) + val web = FallingCobwebEntity(player) web.velocity = player.directionVector.multiply(0.6).addRandom(player.world.random, 0.3f) player.world.spawnEntity(web) } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt index b3e54f7..84cbdbb 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/ability/WallClimbAbility.kt @@ -5,7 +5,7 @@ import gg.norisk.heroes.spiderman.SpidermanManager import net.minecraft.entity.player.PlayerEntity import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable -fun handleClimbCheck(player: PlayerEntity, cir: CallbackInfoReturnable) { +fun handleWallClimbCheck(player: PlayerEntity, cir: CallbackInfoReturnable) { if (player.getHero() == SpidermanManager.Spiderman && !player.isSpectator && player.horizontalCollision) { cir.returnValue = true } diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt new file mode 100644 index 0000000..666849e --- /dev/null +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt @@ -0,0 +1,8 @@ +package gg.norisk.heroes.spiderman.entity + +import net.minecraft.block.Blocks +import net.minecraft.entity.FallingBlockEntity +import net.minecraft.entity.player.PlayerEntity + +class FallingCobwebEntity(val owner: PlayerEntity) + : FallingBlockEntity(owner.world, owner.x, owner.eyePos.y, owner.z, Blocks.COBWEB.defaultState) diff --git a/spiderman/src/main/resources/spiderman.mixins.json b/spiderman/src/main/resources/spiderman.mixins.json index d949029..f8a07c6 100644 --- a/spiderman/src/main/resources/spiderman.mixins.json +++ b/spiderman/src/main/resources/spiderman.mixins.json @@ -7,6 +7,7 @@ "defaultRequire": 1 }, "mixins": [ + "CobwebBlockMixin", "PlayerEntityMixin" ], "client": [ From 99eb701770195f5a3e6737ca6b455b7795fbf114 Mon Sep 17 00:00:00 2001 From: "Fabi.exe" Date: Sat, 22 Mar 2025 12:48:55 +0100 Subject: [PATCH 9/9] feat: better falling cobweb implementation --- .../spiderman/entity/FallingCobwebEntity.kt | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt index 666849e..664f710 100644 --- a/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt +++ b/spiderman/src/main/kotlin/gg/norisk/heroes/spiderman/entity/FallingCobwebEntity.kt @@ -1,8 +1,41 @@ package gg.norisk.heroes.spiderman.entity +import gg.norisk.heroes.common.utils.toBlockPos import net.minecraft.block.Blocks import net.minecraft.entity.FallingBlockEntity +import net.minecraft.entity.MovementType import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.math.Direction -class FallingCobwebEntity(val owner: PlayerEntity) - : FallingBlockEntity(owner.world, owner.x, owner.eyePos.y, owner.z, Blocks.COBWEB.defaultState) +class FallingCobwebEntity(owner: PlayerEntity) + : FallingBlockEntity(owner.world, owner.x, owner.eyePos.y, owner.z, Blocks.COBWEB.defaultState) { + override fun tick() { + if (blockState.isAir) { + discard() + return + } + timeFalling++ + applyGravity() + move(MovementType.SELF, velocity) + tickBlockCollision() + tickPortalTeleportation() + if (!world.isClient && isAlive) { + if (!isOnGround) { + Direction.entries.forEach { + val pos = this.pos.add(0.5, 0.5, 0.5).add(it.doubleVector).toBlockPos() + if (!world.getBlockState(pos).isAir) { + if (world.setBlockState(blockPos, blockState, 3)) { + discard() + } + return + } + } + val y = blockPos.y + if ((timeFalling > 100 && (y <= world.bottomY || y > world.topYInclusive)) || timeFalling > 600) { + discard() + } + } + velocity = velocity.multiply(0.98) + } + } +}