Created
November 24, 2022 15:42
-
-
Save IgnatBeresnev/1d8ae3e956761413cc320b157794fcd4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.beresnev.bot.combat; | |
import me.beresnev.botapi.WowInstance; | |
import me.beresnev.botapi.navigation.Navigation; | |
import me.beresnev.botapi.spells.Spell; | |
import me.beresnev.botapi.units.ICharacter; | |
import me.beresnev.botapi.units.ICreature; | |
import me.beresnev.memoryapi.winapi.components.WinKey; | |
import static java.lang.System.currentTimeMillis; | |
import static me.beresnev.util.Util.sleep; | |
/** | |
* @author Cargeh | |
*/ | |
public abstract class CombatProfile { | |
private static final long TIMEOUT = 5000; | |
private final WowInstance wowInstance; | |
private final ICharacter character; | |
private final Navigation navigation; | |
public CombatProfile(WowInstance wowInstance) { | |
this.wowInstance = wowInstance; | |
this.character = wowInstance.getCharacter(); | |
this.navigation = wowInstance.getNavigation(); | |
} | |
protected abstract Spell[] getRequiredSpells(); | |
public boolean kill(ICreature creature) { | |
int creatureHealth = creature.getHealth(); | |
long timestampOfHealthWrite = currentTimeMillis(); | |
while (creatureHealth > 1) { | |
if (isMelee()) { | |
boolean attackingCreature = attackCreatureMelee(creature); | |
if (!attackingCreature) | |
return false; | |
} else { | |
// TODO: goto as ranged | |
} | |
rotationOn(creature); | |
sleep(getIterationInterval()); | |
int currentCreatureHealth = creature.getHealth(); | |
if (creatureHealth == currentCreatureHealth) { | |
if (isTimeoutReached(timestampOfHealthWrite)) | |
return false; | |
} else { | |
timestampOfHealthWrite = currentTimeMillis(); | |
} | |
creatureHealth = currentCreatureHealth; | |
} | |
return true; | |
} | |
private boolean attackCreatureMelee(ICreature creature) { | |
boolean isThere = navigation.goTo(creature); | |
if (!isThere) | |
return false; | |
faceAndTarget(creature); | |
navigation.attack(creature); | |
wowInstance.shortClick(WinKey.W); | |
wowInstance.shortClick(WinKey.S); | |
return true; | |
} | |
private void faceAndTarget(ICreature creature) { | |
character.target(creature); | |
navigation.face(creature); | |
} | |
protected abstract long getIterationInterval(); | |
private boolean isTimeoutReached(long startedAttacking) { | |
return (currentTimeMillis() - startedAttacking) >= TIMEOUT; | |
} | |
protected abstract void rotationOn(ICreature creature); | |
protected abstract boolean isMelee(); | |
protected abstract int getMinLevel(); | |
protected abstract int getMaxLevel(); | |
boolean isValidLevel(int level) { | |
return level > getMinLevel() && level <= getMaxLevel(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.beresnev.bot.combat.paladin; | |
import me.beresnev.bot.combat.CombatProfile; | |
import me.beresnev.botapi.WowInstance; | |
import me.beresnev.botapi.spells.Spell; | |
import me.beresnev.botapi.spells.Spellbook; | |
import me.beresnev.botapi.units.ICharacter; | |
import me.beresnev.botapi.units.ICreature; | |
import static me.beresnev.botapi.spells.Spell.PALADIN.HOLY_LIGHT; | |
import static me.beresnev.botapi.spells.Spell.PALADIN.SEAL_OF_RIGHTEOUSNESS; | |
/** | |
* @author Cargeh | |
*/ | |
public class PaladinProfileLevel1 extends CombatProfile { | |
private static final int minLevel = 1; | |
private static final int maxLevel = 9; | |
private final ICharacter character; | |
private final Spellbook spellbook; | |
public PaladinProfileLevel1(WowInstance wowInstance) { | |
super(wowInstance); | |
this.character = wowInstance.getCharacter(); | |
this.spellbook = wowInstance.getSpellbook(); | |
} | |
public Spell[] getRequiredSpells() { | |
return new Spell[]{HOLY_LIGHT, SEAL_OF_RIGHTEOUSNESS}; | |
} | |
@Override | |
protected long getIterationInterval() { | |
return 2000; | |
} | |
@Override | |
public void rotationOn(ICreature creature) { | |
if (sealIsNotUp()) | |
reapplySeal(); | |
if (needHeal()) | |
heal(); | |
} | |
@Override | |
public boolean isMelee() { | |
return true; | |
} | |
private boolean sealIsNotUp() { | |
return !character.hasAura(SEAL_OF_RIGHTEOUSNESS); | |
} | |
private void reapplySeal() { | |
spellbook.castSpell(SEAL_OF_RIGHTEOUSNESS); | |
} | |
private boolean needHeal() { | |
return character.getHealthPercentage() <= 30; | |
} | |
private void heal() { | |
spellbook.castSpell(HOLY_LIGHT); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.beresnev.bot.combat; | |
import me.beresnev.botapi.WowInstance; | |
import me.beresnev.botapi.units.ICreature; | |
import static java.lang.System.currentTimeMillis; | |
import static me.beresnev.bot.util.Util.numberIsInBound; | |
/** | |
* @author Cargeh | |
*/ | |
public abstract class Rotation { | |
private static final long LEVEL_CHECK_PERIOD = 600000; // 10 minutes | |
protected final WowInstance wowInstance; | |
private volatile long timestampOfLastLevel = currentTimeMillis(); | |
private volatile CombatProfile combatProfile; | |
public Rotation(WowInstance wowInstance) { | |
this.wowInstance = wowInstance; | |
this.combatProfile = getProfileFor(wowInstance.getCharacter().getLevel()); | |
} | |
public boolean kill(ICreature creature) { | |
updateCombatProfileIfRequired(); | |
return combatProfile.kill(creature); | |
} | |
private void updateCombatProfileIfRequired() { | |
long currentTime = currentTimeMillis(); | |
if ((currentTime - timestampOfLastLevel) >= LEVEL_CHECK_PERIOD) { | |
int characterLevel = wowInstance.getCharacter().getLevel(); | |
if (!combatProfile.isValidLevel(characterLevel)) { | |
combatProfile = getProfileFor(characterLevel); | |
} | |
timestampOfLastLevel = currentTime; | |
} | |
} | |
private CombatProfile getProfileFor(int level) { | |
if (numberIsInBound(level <= 9)) { | |
return getProfileWithValidatedSpellsLevel1(); | |
} else { | |
throw new IllegalArgumentException("Cannot get a profile for level " + level); | |
} | |
} | |
private CombatProfile getProfileWithValidatedSpellsLevel1() { | |
CombatProfile profile = getProfileForLevel1(); | |
checkRequiredSpells(profile); | |
return profile; | |
} | |
public void checkRequiredSpells(CombatProfile combatProfile) { | |
if (characterMissingSpells(combatProfile)) | |
throw new IllegalStateException( | |
"Spells on your character are very outdated. Cannot proceed. Visit the trainer"); | |
} | |
private boolean characterMissingSpells(CombatProfile combatProfile) { | |
return !wowInstance.getSpellbook().characterHasSpells(combatProfile.getRequiredSpells()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment