Jump to content

Hooking to Criteria Triggers?


Lyinginbedmon

Recommended Posts

In the vanilla code there's nearly 30 different criteria triggers that are natively updated and managed and almost none of them also connect to events. At a rough estimate, maybe 21 of them could be replicated using Forge events but this would be impractical and laggy in the extreme. However, the criteria triggers will only add listeners from the PlayerAdvancements class.

 

Criteria seem like a really configurable way of adding special effects and such, but is there any way to use them for more than just add new advancements given this hard-coded restriction?

Link to comment
Share on other sites

What is your use-case here?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

6 minutes ago, Draco18s said:

What is your use-case here?

I can see a number of possible contexts it'd be useful but I ran into this issue trying to make a progression system similar to that of Witchery's vampirism and lycanthropy, but able to configured with the same triggers of advancements.

 

Users provide a config/data pack file with a given "pact" contained within it, it gets broken down into tiers and each is accessed in turn based on given criteria. Just about every step of it I can already implement, but I'm flummoxed by how to interface it with the criteria triggers.

Edited by Lyinginbedmon
Link to comment
Share on other sites

You'd have to see how Advancements uses them, I'm pretty sure you can utilize the existing systems for your own use.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

12 hours ago, Draco18s said:

You'd have to see how Advancements uses them, I'm pretty sure you can utilize the existing systems for your own use.

This much I've already ascertained, more or less.

 

  • Criteria Triggers are held as static final values in the CriteriaTriggers class, each as their own class (ImpossibleTrigger, KilledTrigger, TickTrigger, etc.) and not as a generic.
  • The vanilla code then directly triggers them whenever they are needed, and they update a list of attached listeners when they are so updated.
  • Listeners are added to each trigger via the AddListener method specified in ICriterionTrigger (which only declares 3 methods: addListener, removeListener, and removeAllListeners). This method (and all methods in ICriterionTrigger) requires a PlayerAdvancements input value to register the listener in a hashmap.

 

My problem is finding a way to add a listener to the criteria without using advancements, because no other route seems evident, but so far I've not found anything. I could theoretically extend from PlayerAdvancements, but that's about 500 lines of code that I'm not dreadfully sure of the operation.

Edited by Lyinginbedmon
Link to comment
Share on other sites

Use player.getAdvancements() as your PlayerAdvancements object. The way trigger works is that trigger is passed a player and calls getAdvancements on it in order to get all the listeners. You'll have to do that for every player that joins the server (and call remove when they leave).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

17 hours ago, Draco18s said:

Use player.getAdvancements() as your PlayerAdvancements object. The way trigger works is that trigger is passed a player and calls getAdvancements on it in order to get all the listeners. You'll have to do that for every player that joins the server (and call remove when they leave).

Unfortunately the trouble doesn't just end there, as the Listener we have to manage also requires an Advancement object and makes active use of the value (so we can't just feed it a null). One feasible solution would be to creatively generate dummy advancements but that could cause some considerable bloat in the advancement screen.

	private static final Criterion testCriteria;
	private static final Listener testListener;

	/** Add listeners on login */
	@SideOnly(Side.SERVER)
	@SubscribeEvent
	public void onPlayerLogin(PlayerLoggedInEvent event)
	{
		EntityPlayerMP player = (EntityPlayerMP)event.player;
		PlayerAdvancements advancements = player.getAdvancements();
		CriteriaTriggers.PLAYER_KILLED_ENTITY.addListener(advancements, testListener);
	}
	
	/** Remove listeners on logout */
	@SideOnly(Side.SERVER)
	@SubscribeEvent
	public void onPlayerLogout(PlayerLoggedOutEvent event)
	{
		EntityPlayerMP player = (EntityPlayerMP)event.player;
		PlayerAdvancements advancements = player.getAdvancements();
		CriteriaTriggers.PLAYER_KILLED_ENTITY.removeListener(advancements, testListener);
	}
	
	static
	{
		testCriteria = PactHandler.getPact(new ResourceLocation(Reference.ModInfo.MOD_ID, "feyWitch")).getTiers()[1].getCriteria().get("vax");
		testListener = new ICriterionTrigger.Listener(testCriteria.getCriterionInstance(), null, "vax");
	}

In this quick test example, the criteria (under the name "vax") being added is to kill 1 pig, retrieved from what I've already assembled for a configurable JSON folder.

Edited by Lyinginbedmon
Link to comment
Share on other sites

Hmm, not sure then. I've not tried to do something like this.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.