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

Modificiation for Wizard to stand in oculus ring

Fredoh

Member
Joined
Oct 29, 2014
Messages
147
Reaction score
4
Hello,

Anyone has this type of modification. I remember it was in META for Season 5 but i don't know how to code it !

Thanks
 
I'll try and have a look at it this weekend when I have time if anyone doesn't come up with a fix for it by then.
 
I'm not that familiar with the API. How would you check if there's the Oculus Ring on the floor?
 
A couple months ago someone tried to do this with TH, but I don't think the ring had a SNO or whatever.
 
A couple months ago someone tried to do this with TH, but I don't think the ring had a SNO or whatever.

Hello guys,

I think you may be writing about my posts in ol' Bentag's thread. I made it work for ET wizard in Season 5, it worked well, let me speedrun (8-10m) GR96, push GR100 with about 50% success rate. Unfortunately I need few more weeks before I get to diabling again and there is no time to fix this for Season 6 atm. But maybe I can save you some time with this:

Detecting Oculus rings is actually the simple part of the problem (of course, the shiny rings on the ground have SNO's). This piece of code will detect oculus buffs up to range (defaul=20) of your current target. I used current target as the distance reference point because of the Audicity passive. You can use Player's position as the reference point.
Code:
	// Get reference to the oculus buff closest to your current target
	internal static DiaObject GetOculusBuffDiaObject(float range = 20f)
	{
		 var objects = ZetaDia.Actors.GetActorsOfType<DiaObject>()
                        .Where(o => o.ActorSnoId == 433966 && CurrentTarget.Position.Distance(o.Position) < range)
                        .OrderBy(o => CurrentTarget.Position.Distance(o.Position));
		
		 foreach (DiaObject o in objects)
		{
			if (o == null || !o.IsValid) continue;
			return o;
		}
		return null;
	}
For some reason, the centre of the detected oculus buff is about 18 distance units under the lowest level, so you have to take z-coordinate from the Player.Position. So for example modifying teleport part of WizardCombat.cs will look like this:
Code:
            if (CanCastTeleport())
            {
                Vector3 telespot;
                DiaObject ocul = TargetUtil.GetOculusBuffDiaObject();
                if (ocul) {
                  telespot.X = ocul.Position.X;
                  telespot.Y = ocul.Position.Y;
                  telespot.Z = Player.Position.Z;
		} else {
                  telespot = something_else;
                }
                return new TrinityPower(SNOPower.Wizard_Teleport, 65f, telespot);
            }

The more difficult part is to solve the movement. From my limited understanding of Trinity's combat I gather that GetPower() (in WizardCombat.cs) is called TPS times per second. Let' say TPS=20. GetPower() always returns a Power (spell, movement, melee attack), it never returns null. The order of priority is given from the top to down of GetPower(): avoidance -> buffs -> power_spenders -> power_generators -> default_power (which is the melee attack). As long as you have power demonbuddy will send 20 spells per second and let the server decide if the spell can be cast or not depending on the attack speed of your character. Typically you can only cast 1-3 spells per second. So where to put the command to move you to the oculus buff? I see 2 options:

1.) You can put it as a high priority movement between buffs and power_spenders. You must synchronize this decision with your avoidance settings and implement ignoring oculus buffs in avoidance areas being damn sure both parts of codes (avoidance movement and your oculus buffs in avoidance areas) see the same avoidance zones. Otherwise your character will shake left and right. Moreover, this implementation will not work if you do not have power_generator, because once you cannot cast a power_spender your GetPower() will fall down and call melee attack that will move you outta oculus buff. This was my problem with Season 5 ET wizard with no power_generator.

2.) Second option is to put the movement to oculus buffs to Teleport spell and to the bottom of the priority list - to the default_power. In Season 5 I replaced default_power with TrinityPower(SNOPower.Walk, ocul.Distance, oculspot). In this case you also have to add delay check to power_spenders, otherwise they will be spammed before the code gets to the default_power part. The delay is determined by your current attackspeed by delayms = 1000.0f/ZetaDia.Me.AttacksPerSecond. This will create time windows in between your casts (you cannot cast in anyway) that will allow your GetPower() fall down to default_power and oculus movement. This is the implementation I did previous season and it worked nicely.

Because of my limited understanding of Trinity I am sure there are some other issues to consider for a general combat routine. My old Season 5 modifications to TargetUtil.cs and WizardCombat.cz are below. May you find it useful.
View attachment TargetUtil.cs
View attachment WizardCombat.cs
 
Last edited:
Hello guys,

I think you may be writing about my posts in ol' Bentag's thread. I made it work for ET wizard in Season 5, it worked well, let me speedrun (8-10m) GR96, push GR100 with about 50% success rate. Unfortunately I need few more weeks before I get to diabling again and there is no time to fix this for Season 6 atm. But maybe I can save you some time with this:

Detecting Oculus rings is actually the simple part of the problem (of course, the shiny rings on the ground have SNO's). This piece of code will detect oculus buffs up to range (defaul=20) of your current target. I used current target as the distance reference point because of the Audicity passive. You can use Player's position as the reference point.
Code:
	// Get reference to the oculus buff closest to your current target
	internal static DiaObject GetOculusBuffDiaObject(float range = 20f)
	{
		 var objects = ZetaDia.Actors.GetActorsOfType<DiaObject>()
                        .Where(o => o.ActorSnoId == 433966 && CurrentTarget.Position.Distance(o.Position) < range)
                        .OrderBy(o => CurrentTarget.Position.Distance(o.Position));
		
		 foreach (DiaObject o in objects)
		{
			if (o == null || !o.IsValid) continue;
			return o;
		}
		return null;
	}
For some reason, the centre of the detected oculus buff is about 18 distance units under the lowest level, so you have to take z-coordinate from the Player.Position. So for example modifying teleport part of WizardCombat.cs will look like this:
Code:
            if (CanCastTeleport())
            {
                Vector3 telespot;
                DiaObject ocul = TargetUtil.GetOculusBuffDiaObject();
                if (ocul) {
                  telespot.X = ocul.Position.X;
                  telespot.Y = ocul.Position.Y;
                  telespot.Z = Player.Position.Z;
		} else {
                  telespot = something_else;
                }
                return new TrinityPower(SNOPower.Wizard_Teleport, 65f, telespot);
            }

The more difficult part is to solve the movement. From my limited understanding of Trinity's combat I gather that GetPower() (in WizardCombat.cs) is called TPS times per second. Let' say TPS=20. GetPower() always returns a Power (spell, movement, melee attack), it never returns null. The order of priority is given from the top to down of GetPower(): avoidance -> buffs -> power_spenders -> power_generators -> default_power (which is the melee attack). As long as you have power demonbuddy will send 20 spells per second and let the server decide if the spell can be cast or not depending on the attack speed of your character. Typically you can only cast 1-3 spells per second. So where to put the command to move you to the oculus buff? I see 2 options:

1.) You can put it as a high priority movement between buffs and power_spenders. You must synchronize this decision with your avoidance settings and implement ignoring oculus buffs in avoidance areas being damn sure both parts of codes (avoidance movement and your oculus buffs in avoidance areas) see the same avoidance zones. Otherwise your character will shake left and right. Moreover, this implementation will not work if you do not have power_generator, because once you cannot cast a power_spender your GetPower() will fall down and call melee attack that will move you outta oculus buff. This was my problem with Season 5 ET wizard with no power_generator.

2.) Second option is to put the movement to oculus buffs to Teleport spell and to the bottom of the priority list - to the default_power. In Season 5 I replaced default_power with TrinityPower(SNOPower.Walk, ocul.Distance, oculspot). In this case you also have to add delay check to power_spenders, otherwise they will be spammed before the code gets to the default_power part. The delay is determined by your current attackspeed by delayms = 1000.0f/ZetaDia.Me.AttacksPerSecond. This will create time windows in between your casts (you cannot cast in anyway) that will allow your GetPower() fall down to default_power and oculus movement. This is the implementation I did previous season and it worked nicely.

Because of my limited understanding of Trinity I am sure there are some other issues to consider for a general combat routine. My old Season 5 modifications to TargetUtil.cs and WizardCombat.cz are below. May you find it useful.
View attachment 201799
View attachment 201800


Hi Tempest, witch build and setup u have ?
Tnx Fedez
 
Ah - my mistake for not knowing there was a SNO. Not that I could have come up with what Tempest did.

Hi Tempest, witch build and setup u have ?
Tnx Fedez

Tempest said:
Unfortunately I need few more weeks before I get to diabling again and there is no time to fix this for Season 6 atm. But maybe I can save you some time with this:
 
Hi Tempest, witch build and setup u have ?
Tnx Fedez

Fedez,
as Relomy pointed out those modification are valid for Season 5 only. I posted that as an introduction to Oculus ring topic to make it easier for someone who wants to implement Oculus buff into Trinity's combat quickly. If the problem is not solved following 3 weeks I will have time to sit on it and do a dirty implementation for one wizard build that will be the current META dps build.
 
found also old stuff of the 200b/h 4 Man Group-Stuff

twizard.cs:
// Roman
// Periodic Teleport: SafePassage
if (CanCastTeleport())
{
Vector3 telespot;
if (TargetUtil.OculusBuffInRange())
{
DiaObject ocul = TargetUtil.GetOculusBuffDiaObject();
telespot.X = ocul.Position.X;
telespot.Y = ocul.Position.Y;
telespot.Z = Player.Position.Z;
//Logger.Log("-- Periodic teleport to {0},{1}, with distance {2}",ocul.Position.X, ocul.Position.Y,ocul.Distance);
}
else
{

var target = KiteDistance == 0 ? TargetUtil.GetBestClusterPoint() : NavHelper.FindSafeZone(false, 1, CurrentTarget.Position, true);
// Teleporting exactly on top of targets prevents them from taking damage
telespot = MathEx.GetPointAt(target, 4f, Player.Rotation);
}
return new TrinityPower(SNOPower.Wizard_Teleport, 50f, telespot);
}



.
.
.




if (CanCastTeleport())
{
Vector3 telespot;
if (TargetUtil.OculusBuffInRange())
{
DiaObject ocul = TargetUtil.GetOculusBuffDiaObject();
telespot.X = ocul.Position.X;
telespot.Y = ocul.Position.Y;
telespot.Z = Player.Position.Z;
//Logger.Log("-- Periodic teleport to {0},{1}, with distance {2}",ocul.Position.X, ocul.Position.Y,ocul.Distance);
}
else
{

var target = KiteDistance == 0 ? TargetUtil.GetBestClusterPoint() : NavHelper.FindSafeZone(false, 1, CurrentTarget.Position, true);
// Teleporting exactly on top of targets prevents them from taking damage
telespot = MathEx.GetPointAt(target, 4f, Player.Rotation);
}
return new TrinityPower(SNOPower.Wizard_Teleport, 50f, telespot);
}

.
.
.
.




Vector3 oculspot;
if (TargetUtil.OculusBuffInRange())
{
DiaObject ocul = TargetUtil.GetOculusBuffDiaObject();
oculspot.X = ocul.Position.X;
oculspot.Y = ocul.Position.Y;
oculspot.Z = Player.Position.Z;
//Logger.Log("-- Walking to Teleport to {0},{1}, with distance {2}",ocul.Position.X, ocul.Position.Y,ocul.Distance);
if (Player.Position.Distance(oculspot) <= 5f)
{
power = new TrinityPower(SNOPower.Walk, 35f, Vector3.Zero);
}
else
{
power = new TrinityPower(SNOPower.Walk, ocul.Distance, oculspot);
}
}
else
{

// Decide wheter to use melee or ranged attacks
var isMeleeWiz = (Sets.TalRashasElements.IsFullyEquipped && Legendary.WandOfWoh.IsEquipped ||
Sets.DelseresMagnumOpus.IsFullyEquipped && Skills.Wizard.ArcaneOrb.IsActive ||
Sets.VyrsAmazingArcana.IsFullyEquipped && Sets.ChantodosResolve.IsFullyEquipped);
/* if (!isMeleeWiz && CurrentTarget != null)
power = DefaultPower.MinimumRange > 11f ? DefaultPower : new TrinityPower(SNOPower.Walk);

else */
if (isMeleeWiz)
power = new TrinityPower(SNOPower.Walk, CurrentTarget.RadiusDistance, CurrentTarget.Position);
}
 
The issue is that we are not using teleport in season 6 with TAL build....
 
Took me a while to make, but it works great, so good that I doubt a human can move this efficiently :D

[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=4 TotalTwisters=5 TwistedSwordFakeStacks=9/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=True ClosestPointDistance=-6.445176 (minus means its cutting into the other circle)
[Trinity 2.41.42] Moving to oculusinnersanc=<770.7739, 957.9814, 0.1000001>
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=True ClosestPointDistance=-6.445176 (minus means its cutting into the other circle)
[Trinity 2.41.42] Moving to oculusinnersanc=<770.7739, 957.9814, 0.1000007>
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=4 TotalTwisters=5 TwistedSwordFakeStacks=9/13
[Trinity 2.41.42] > Inside InnerSancOculus
 
Took me a while to make, but it works great, so good that I doubt a human can move this efficiently :D

[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=0 BigTwisters=4 TotalTwisters=4 TwistedSwordFakeStacks=8/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=False ClosestPointDistance=1.227094 (minus means its cutting into the other circle)
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=4 TotalTwisters=5 TwistedSwordFakeStacks=9/13
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=True ClosestPointDistance=-6.445176 (minus means its cutting into the other circle)
[Trinity 2.41.42] Moving to oculusinnersanc=<770.7739, 957.9814, 0.1000001>
[Trinity 2.41.42] > Found InnerSancOculus, DoTheyOverlap=True ClosestPointDistance=-6.445176 (minus means its cutting into the other circle)
[Trinity 2.41.42] Moving to oculusinnersanc=<770.7739, 957.9814, 0.1000007>
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=3 TotalTwisters=4 TwistedSwordFakeStacks=7/13
[Trinity 2.41.42] > Inside InnerSancOculus
[Trinity 2.41.42] Casting Energy Twister, SmallTwisters=1 BigTwisters=4 TotalTwisters=5 TwistedSwordFakeStacks=9/13
[Trinity 2.41.42] > Inside InnerSancOculus

Can you share the code or upload file(s) ?
 
Back
Top