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

Scale Attack Range with Pehkui's entity scale #49

Closed
bassistracer opened this issue Aug 15, 2022 · 16 comments
Closed

Scale Attack Range with Pehkui's entity scale #49

bassistracer opened this issue Aug 15, 2022 · 16 comments
Labels
enhancement New feature or request external help needed waiting for release There's nothing in the world that breeds success like success

Comments

@bassistracer
Copy link

Just an idea for something long down the road, but, I figured this is probably one of the easier ways to add compatibility between Better Combat and Pehkui.
So, if Pehkui doubles your "block reach" by 2, your attack range likewise multiplies by 2 -- and vise versa.
The reason why I mention "block reach" specifically is because it's usually calculated when growing or shrinking players' base height.
Assuming this wouldn't be a total pain in the arse to program, that is. Thanks for reading.

@ZsoltMolnarrr ZsoltMolnarrr changed the title [Enhancement] Dynamic Attack Range with Pehkui's "block reach" function Scale Attack Range with Pehkui's entity scale Aug 17, 2022
@ZsoltMolnarrr
Copy link
Owner

Hello!
Theoretically I could scale the attack range of the player using the scale from Pekhui.
Unfortunately that mod doesn't seem to offer any attribute I can rely on without an explicit dependency.

@ZsoltMolnarrr ZsoltMolnarrr added the enhancement New feature or request label Aug 17, 2022
@bassistracer
Copy link
Author

Hello! Theoretically I could scale the attack range of the player using the scale from Pekhui. Unfortunately that mod doesn't seem to offer any attribute I can rely on without an explicit dependency.

That's strange -- usually something like this should just make it an optional dependency as opposed to a mandatory one. I'll ask around and see if there's any way to just make it the former.

@ZsoltMolnarrr
Copy link
Owner

ZsoltMolnarrr commented Aug 17, 2022

Just to clarify:
I don't want to introduce ANY gradle dependency on Pehkui.

On the other hand I am open for communicating with that mod via Minecraft's Vanilla API. If there is a scale EntityAttribute Pehkui introduces, I could use the value of that. However their developer documentation contains no information in this regard.
Nor does the developer seem to have a Discord server I was able to find.

@Virtuoel
Copy link

Since you mentioned using attributes, instead of using Pehkui directly it would probably be better if you were to make use of Reach-Entity-Attributes, which Pehkui has compat code for to adjust the attribute values based on one's scale. Would also improve compat with other Fabric mods that adjust attack and block reach.

@ZsoltMolnarrr
Copy link
Owner

Hi!
Thanks for the reply!:)
Better Combat has a custom target lookup and collision detection code.
I think REA would not help, because Better Combat is independent from Vanilla targeting mechanics.

I think the correct solution is for Better Combat to obtain the scale (float value) of the player, so the OBB used for weapon collision could be scaled with it.

What do you think, what would be a good way to obtain this?

@Virtuoel
Copy link

I would not consider the following as a good way in the slightest, but, a way to obtain a scale without a dependency would be something equivalent to this terrible chunk of reflection:

Show/Hide Reflection
private static final Method GET_SCALE_DATA;
private static final Method GET_SCALE;
private static final Map<Identifier, Object> SCALE_TYPES;

static
{
	Method getScaleDataMethod = null;
	Method getScaleMethod = null;
	Map<Identifier, Object> scaleTypes = null;
	
	if (FabricLoader.getInstance().isModLoaded("pehkui"))
	{
		try
		{
			Class<?> scaleTypeClass = Class.forName("virtuoel.pehkui.api.ScaleType");
			Class<?> scaleDataClass = Class.forName("virtuoel.pehkui.api.ScaleData");
			Class<?> scaleRegistriesClass = Class.forName("virtuoel.pehkui.api.ScaleRegistries");
			Field scaleTypesField = scaleRegistriesClass.getField("SCALE_TYPES");
			
			getScaleDataMethod = scaleTypeClass.getMethod("getScaleData", Entity.class);
			getScaleMethod = scaleDataClass.getMethod("getScale", float.class);
			scaleTypes = (Map<Identifier, Object>) scaleTypesField.get(null);
		}
		catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException e)
		{
			getScaleDataMethod = null;
			getScaleMethod = null;
			scaleTypes = null;
		}
	}
	
	GET_SCALE_DATA = getScaleDataMethod;
	GET_SCALE = getScaleMethod;
	SCALE_TYPES = scaleTypes;
}

public static float getScale(Entity entity, Identifier scaleId)
{
	return getScale(entity, scaleId, 1.0F);
}

public static float getScale(Entity entity, Identifier scaleId, float tickDelta)
{
	if (GET_SCALE_DATA != null && GET_SCALE != null && SCALE_TYPES != null)
	{
		try
		{
			return (float) GET_SCALE.invoke(GET_SCALE_DATA.invoke(SCALE_TYPES.get(scaleId), entity), tickDelta);
		}
		catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
		{
			return 1.0F;
		}
	}
	
	return 1.0F;
}

@ZsoltMolnarrr
Copy link
Owner

Thanks for all this code. Yes this looks rather suboptimal.
Just out of curiosity, what is the reason behind not storing the scale in an entity attribute?

That way any mod could add compatibility easily.
For example player.getAttributeValue(Registry.ATTRIBUTE.getId("generic.scale")

@Virtuoel
Copy link

Virtuoel commented Aug 17, 2022

Unfortunately attributes are limited to living entities, while scales are applicable to every entity, living or otherwise.

@bassistracer
Copy link
Author

Just a thought that popped up in my head, not exactly sure if it counts for your goal of not needing a dependency in mind, but something you could theoretically do, should that code not work out right, is release an extension mod for Better Combat that uses Pehkui scales.

An example would be here with Create Support for Open Parties and Claims; a mod separate from 'Open Parties and Claims' that uses Create as a dependency so that the main mod doesn't need Create as a dependency.

@bassistracer bassistracer closed this as not planned Won't fix, can't repro, duplicate, stale Aug 19, 2022
@bassistracer bassistracer reopened this Aug 19, 2022
@ZsoltMolnarrr
Copy link
Owner

It sounds like a nice idea, but in reality it scales rather poorly.
Maintaining additional release variants is costly.

Maybe I'll use the reflection based solution mentioned by @Virtuoel . BTW @Virtuoel does this work in a release environment (after remapping jars)?

@Virtuoel
Copy link

I've run it in both dev and prod, and since the strings passed to the reflection don't reference vanilla classes, only Pehkui ones, it does work outside the dev enviroment, yes.
(note that Pehkui 3.4.0 is currently buggy, so I recommend doing any testing with 3.3.3, or with 3.4.1 once I get to releasing that this weekend.)

@ZsoltMolnarrr
Copy link
Owner

public static float getScale(Entity entity, Identifier scaleId)
{
	return getScale(entity, scaleId, 1.0F);
}

What would be the scaledId argument?

@Virtuoel
Copy link

It'd be new Identifier("pehkui", <type>), with the path parameter being one of the scale type ID strings used here, from whichever property is best suited to affecting the attack range of your weapons. My guess would be entity_reach or block_reach, but it's up to you.

@ZsoltMolnarrr
Copy link
Owner

I created a Pekhui integration branch, using the reflection based solution.

Unfortunately I am getting the following crash:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "obj" is null
	at java.base/java.lang.reflect.Method.invoke(Method.java:561)
	at net.bettercombat.fabric.client.PekhuiIntegration.getScale(PekhuiIntegration.java:60)
	at net.bettercombat.fabric.client.PekhuiIntegration.getScale(PekhuiIntegration.java:51)
	at net.bettercombat.fabric.PlatformClientImpl.getEntityScale(PlatformClientImpl.java:9)
	at net.bettercombat.PlatformClient.getEntityScale(PlatformClient.java)
	at net.bettercombat.client.collision.TargetFinder.findAttackTargetResult(TargetFinder.java:30)
	at net.minecraft.client.render.debug.DebugRenderer.handler$bce000$renderColliderDebug(DebugRenderer.java:554)
	at net.minecraft.client.render.debug.DebugRenderer.render(DebugRenderer.java:132)
	at net.minecraft.client.render.WorldRenderer.render(WorldRenderer.java:1182)
	at net.minecraft.client.render.GameRenderer.renderWorld(GameRenderer.java:1024)
	at net.minecraft.client.render.GameRenderer.render(GameRenderer.java:833)
	at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1101)
	at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:751)
	at net.minecraft.client.main.Main.main(Main.java:220)
	at net.minecraft.client.main.Main.main(Main.java:56)
	at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:461)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
	at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
	at dev.architectury.transformer.TransformerRuntime.main(TransformerRuntime.java:217)

I am really not sure if reflection based solution can be stable in the long term.

Is there no way to provide the scale values via any Vanilla API?

@Virtuoel
Copy link

Looks like the crash is because you misspelt pehkui as pekhui in the Identifier. Also since Pehkui has a Forge version you don't need to keep the compat Fabric-specific.

@ZsoltMolnarrr
Copy link
Owner

Wow big mistake from my part, sorry!
Thanks for the help!

@ZsoltMolnarrr ZsoltMolnarrr added the waiting for release There's nothing in the world that breeds success like success label Aug 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request external help needed waiting for release There's nothing in the world that breeds success like success
Projects
None yet
Development

No branches or pull requests

3 participants