What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal
RebornBuddy Forums

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

TreeHooks.Instance.Hooks and TreeHooks.Instance.HookDescriptions

RahlRB

New Member
Joined
Sep 24, 2015
Messages
20
Mastahg,

I am currently getting some very interesting behavior out of the following 2 API calls:
  • TreeHooks.Instance.Hooks
  • TreeHooks.Instance.HookDescriptions

I am currently using the following code to test these in the RebornConsole:

Code:
Log(BotManager.Current.EnglishName);
Log("\n");
foreach (var hook in ff14bot.Behavior.TreeHooks.Instance.Hooks)
{
	Log(hook.Key);
}
Log("\n");
foreach (var hookDescription in ff14bot.Behavior.TreeHooks.Instance.HookDescriptions)
{
    Log(hookDescription.Name + ":\t" + hookDescription.Description);
}

Currently, when I just start a brand new instance of RB and I haven't actually started any BotBase, when I run the above code this is what I'm getting:

Code:
Combat Assist


TreeStart
PoiAction
PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest

Notice how I'm getting the name of the Hooks, but I'm not getting any HookDescriptions at all.

Now is where things are really getting weird for me and I don't understand what is causing them to happen. As soon as I hit Start on RB to start running the BotBase, I now get this result from running the same code snippet in the Console:

Code:
Combat Assist


TreeStart
PoiAction
PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest
DeathReturnLogic


DeathReturnLogic:	This logic runs if the player has died and succesfully revied

Notice how we have a new Hook showing up (DeathReturnLogic) and we are finally getting a HookDescription as well (for DeathReturnLogic).

Why this is weird to me is because I've looked at the code in RaidBro.cs (Combat Assist) and I don't see it adding a new HookExecutor or a new HookDescription anywhere.

Further confusion is caused when I click the Stop button in RB. After clicking Stop and re-running the same code snippet, I get the following results:

Code:
Combat Assist


TreeStart
PoiAction
PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest
DeathReturnLogic


DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied

It looks like there is something wrong within the BotStop methods somewhere. The reason I say this, is because if I click Start and then run the code snippet again, I get the same results...but as soon as I hit Stop and then run the code snippet again, I get another duplicate entry in the HookDescriptions.

Here's a result after Starting/Stopping the bot many times:

Code:
Combat Assist


TreeStart
PoiAction
PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest
DeathReturnLogic


DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied
DeathReturnLogic:	This logic runs if the player has died and succesfully revied

Can you give any insight on why the API is inserting a new hook (DeathReturnLogic). Can you also look into the duplicate entries into the HookDescriptions.

Thanks,

Rahl
 

Attachments

PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest

are internal hooks used to support the swapping of combat routines and as such do not have descriptions.

deathreturnlogic is the hook that is used to handle getting back to where you are when you die. We don't check if its already added and since it doesn't effect anything im going to leave it.
 
PreCombatBuff
Heal
Pull
CombatBuff
Combat
Rest

are internal hooks used to support the swapping of combat routines and as such do not have descriptions.

deathreturnlogic is the hook that is used to handle getting back to where you are when you die. We don't check if its already added and since it doesn't effect anything im going to leave it.

Thank you for the clarification.

Since the above mentioned hooks are internal, should we not use those hooks in custom botbases?

IE: Is something like this bad practice?

Code:
if (RoutineManager.Current.CombatBehavior != null)
{
	foreach (var action in TreeHooks.Instance.Hooks["Combat"])
	{
		try
		{
			if (await action.ExecuteCoroutine()) return true;
		}
		catch (Exception ex)
		{
			Logging.WriteException(Colors.Red, ex);
		}
		await Coroutine.Yield();
	}
	if (await RoutineManager.Current.CombatBehavior.ExecuteCoroutine()) return true;
}
 
Thank you for the clarification.

Since the above mentioned hooks are internal, should we not use those hooks in custom botbases?

IE: Is something like this bad practice?

Code:
if (RoutineManager.Current.CombatBehavior != null)
{
	foreach (var action in TreeHooks.Instance.Hooks["Combat"])
	{
		try
		{
			if (await action.ExecuteCoroutine()) return true;
		}
		catch (Exception ex)
		{
			Logging.WriteException(Colors.Red, ex);
		}
		await Coroutine.Yield();
	}
	if (await RoutineManager.Current.CombatBehavior.ExecuteCoroutine()) return true;
}

They should not be used. And im not sure what your trying to do there either.
 
They should not be used. And im not sure what your trying to do there either.

In essence, what I'm trying to do is figure out how to execute the hooks that Plugins are attaching to in a custom botbase. I've taken a look at the botbases that come with RB and didn't see an example of how to do that. I added in using the internal hooks because I was going off of memory that you advised Neverdyne to hook into a PreCombat hook for his Zekken Plugin (Zekkenl).

I've just looked at the source for that Zekken Plugin and realized that he is hooking to "PreCombatLogic" which I'm assuming is a custom HookExecutor that you've created.

I know that most plugins are just hooking themselves to the TreeStart Hook, so I came up with the following code to actually execute those plugins:

Code:
public static class Hooks
{
	static Hooks()
	{
		Composite = new ActionRunCoroutine(ctx => Run());
	}
	public static Composite Execute()
	{
		return Composite;
	}

	private static readonly Composite Composite;

	private static async Task<bool> Run()
	{
		foreach (var action in TreeHooks.Instance.Hooks["TreeStart"])
		{
			try
			{
				if (await action.ExecuteCoroutine()) return true;
			}
			catch (Exception ex)
			{
				Logging.WriteException(Colors.Red, ex);
			}
			await Coroutine.Yield();
		}
		return false;
	}
}

And that code gets used in the Root Composite of the BotBase...which looks like this:

Code:
Root = new Decorator(r => Core.Me.IsAlive,
                       new PrioritySelector(
                           Tank.Execute(),
                           Healer.Execute(),
                           Damage.Execute(),
                           Helpers.Execute(),
                           Hooks.Execute()));

I've tested that the above code does actually work by using a simple eat food if I don't have the food buff plugin.

If you would be willing to share some sample code for best practices around executing all of the composites that have been hooked into one of the TreeHooks, that would be great!

Thanks,
 
In essence, what I'm trying to do is figure out how to execute the hooks that Plugins are attaching to in a custom botbase. I've taken a look at the botbases that come with RB and didn't see an example of how to do that. I added in using the internal hooks because I was going off of memory that you advised Neverdyne to hook into a PreCombat hook for his Zekken Plugin (Zekkenl).

I've just looked at the source for that Zekken Plugin and realized that he is hooking to "PreCombatLogic" which I'm assuming is a custom HookExecutor that you've created.

I know that most plugins are just hooking themselves to the TreeStart Hook, so I came up with the following code to actually execute those plugins:

Code:
public static class Hooks
{
	static Hooks()
	{
		Composite = new ActionRunCoroutine(ctx => Run());
	}
	public static Composite Execute()
	{
		return Composite;
	}

	private static readonly Composite Composite;

	private static async Task<bool> Run()
	{
		foreach (var action in TreeHooks.Instance.Hooks["TreeStart"])
		{
			try
			{
				if (await action.ExecuteCoroutine()) return true;
			}
			catch (Exception ex)
			{
				Logging.WriteException(Colors.Red, ex);
			}
			await Coroutine.Yield();
		}
		return false;
	}
}

And that code gets used in the Root Composite of the BotBase...which looks like this:

Code:
Root = new Decorator(r => Core.Me.IsAlive,
                       new PrioritySelector(
                           Tank.Execute(),
                           Healer.Execute(),
                           Damage.Execute(),
                           Helpers.Execute(),
                           Hooks.Execute()));

I've tested that the above code does actually work by using a simple eat food if I don't have the food buff plugin.

If you would be willing to share some sample code for best practices around executing all of the composites that have been hooked into one of the TreeHooks, that would be great!

Thanks,

What you want is HookExecutor

Code:
 new PrioritySelector(new HookExecutor("PreCombatLogic"));
 
What you want is HookExecutor

Code:
 new PrioritySelector(new HookExecutor("PreCombatLogic"));

Well don't I feel silly...thanks! That makes things a lot simpler!

Based off the Summary on the class itself:

//
// Summary:
// A simple Action composite, to facilitate executing TreeHook composites. It is
// not recommended you use this for any built-in hooks. Only use this if using a
// custom hook location!
//
// Remarks:
// Created 3/22/2011.

I thought HookExecutor was only used to define your own custom hook locations to allow others to attach to.

Code:
            Root = new Decorator(r => Core.Me.IsAlive,
                       new PrioritySelector(
                           Tank.Execute(),
                           Healer.Execute(),
                           Damage.Execute(),
                           Helpers.Execute(),
                           new HookExecutor("TreeStart")));

^^ Much simpler now!

Thanks again for the clarification.

-Rahl
 
HookExecutor runs whatever hooks are attached to whatever string is passed.
 
Back
Top