xsol
Member
- Joined
- Nov 7, 2011
- Messages
- 503
CC Logic Timed Rotations
I'm probably going to be busy playing D3 for the next few days, but I wanted to post this before I vanish in case it is needed.
Note: this is untested in this version and is currently only the expression of a concept. I probably will not be around to help with this for a few days. I've fully tested the idea; not this code.
FFS, In the Marksmanship/Sharpshooter CC there is a strong need to execute exactly this rotation over a long duration and stay in that rotation or variant rotation. For the past few days I have been struggling to do just that and I finally had to go back to a method I was using 7 years ago to get it working.
The basic idea is to walk a stack/list and sleep between entries for the time it takes to cast the current ability. I have a class specific version in place for my development copy of sniper currently that works very well.
This is an untested class I have thrown together that may handle doing this:
This is an example of how you could use this in a cc:
I'm probably going to be busy playing D3 for the next few days, but I wanted to post this before I vanish in case it is needed.
Note: this is untested in this version and is currently only the expression of a concept. I probably will not be around to help with this for a few days. I've fully tested the idea; not this code.
FFS, In the Marksmanship/Sharpshooter CC there is a strong need to execute exactly this rotation over a long duration and stay in that rotation or variant rotation. For the past few days I have been struggling to do just that and I finally had to go back to a method I was using 7 years ago to get it working.
The basic idea is to walk a stack/list and sleep between entries for the time it takes to cast the current ability. I have a class specific version in place for my development copy of sniper currently that works very well.
This is an untested class I have thrown together that may handle doing this:
PHP:
public class TimedRotation
{
private int resourceCheck = 0;
private List<string> skills = new List<string>();
private DateTime skillCheck = DateTime.Now;
private Dictionary<string, Composite> skillsEx = new Dictionary<string, Composite>();
private Dictionary<string, int> skillTimers = new Dictionary<string, int>();
private Stack<string> rotationStack = new Stack<string>();
private string lastSkill = string.Empty;
private string currentSkill = string.Empty;
public TimedRotation(int minResourceStat)
{
resourceCheck = minResourceStat;
}
public int SkillCount
{
get
{
return skills.Count;
}
}
public void Add(string spell, int timer, Composite cast)
{
skills.Add(spell);
skillsEx.Add(spell,cast);
skillTimers.Add(spell, timer);
}
public void ReadRotation()
{
if (rotationStack.Count == 0)
{
for (int i = 0; i < skills.Count; i++)
{
rotationStack.Push(skills[i]);
}
}
currentSkill = rotationStack.Pop();
}
public void ResetState()
{
currentSkill = string.Empty;
}
public CanRunDecoratorDelegate CheckSkillTimer()
{
if (currentSkill == string.Empty)
return c => true;
double elapsed = DateTime.Now.Subtract(skillCheck).TotalSeconds;
int timer = skillTimers[currentSkill];
return c => ((elapsed >= timer));
}
public CanRunDecoratorDelegate ShouldCastNow()
{
//false if idle
if (currentSkill == string.Empty)
return c => false;
return c => ((lastSkill != string.Empty && currentSkill != string.Empty) || lastSkill != currentSkill);
}
public Composite GetCaster()
{
return skillsEx[currentSkill];
}
public PrioritySelector ActionSelector ()
{
return new PrioritySelector(
Movement.StopInRange(Global.rangeDist),
Spell.WaitForCast(),
//this literally advances the play head
new Decorator(
CheckSkillTimer(),
new Sequence(
new Action(atn => ReadRotation())
)
),
//this will cast once and then wait for the playhead to advance
new Decorator(
ShouldCastNow(),
new Sequence(
new Action(atn => lastSkill = currentSkill),
GetCaster()
)
)
);
}
}
This is an example of how you could use this in a cc:
PHP:
internal class syntaxCheck
{
private static TimedRotation sniperMarksmanship = new TimedRotation(65);
private static PrioritySelector test = new PrioritySelector(
//build the list if it is not in place
new Decorator(
check => (sniperMarksmanship.SkillCount == 0),
new Sequence(
new Action(atn => sniperMarksmanship.Add("Series of Shots", 7, Spell.Cast("Series of Shots"))),
new Action(atn => sniperMarksmanship.Add("Ambush", 5, Spell.Cast("Ambush"))),
new Action(atn => sniperMarksmanship.Add("Followthrough", 2, Spell.Cast("Followthrough"))),
new Action(atn => sniperMarksmanship.Add("Fragmentation Grenade", 2, Spell.Cast("Fragmentation Grenade"))),
new Action(atn => sniperMarksmanship.Add("Explosive Probe", 2, Spell.Cast("Explosive Probe"))),
new Action(atn => sniperMarksmanship.Add("Snipe", 2, Spell.Cast("Snipe"))),
new Action(atn => sniperMarksmanship.Add("Followthrough", 2, Spell.Cast("Followthrough"))),
new Action(atn => sniperMarksmanship.Add("Fragmentation Grenade", 2, Spell.Cast("Fragmentation Grenade"))),
new Action(atn => sniperMarksmanship.Add("Rifle Shot", 2, Spell.Cast("Rifle Shot"))),
new Action(atn => sniperMarksmanship.Add("Snipe", 2, Spell.Cast("Snipe"))),
new Action(atn => sniperMarksmanship.Add("Followthrough", 2, Spell.Cast("Followthrough")))
)
),
//run the list
new Decorator(
check => (sniperMarksmanship.SkillCount >= 0),
sniperMarksmanship.ActionSelector()
)
);
}
- If no one takes an interest and tests this I will test it when I have the chance in a few days.