use of eidolons.entity.active.DC_SpellObj in project Eidolons by IDemiurge.
the class SpellRadialManager method constructNestedSpellNodes.
private static List<RadialValueContainer> constructNestedSpellNodes(List<DC_SpellObj> spells, Unit source, DC_Obj target) {
Set<SPELL_GROUP> spell_groups = new HashSet<>();
List<SPELL_ASPECT> aspects = new ArrayList<>();
for (DC_SpellObj spell : spells) {
SPELL_GROUP group = spell.getSpellGroup();
spell_groups.add(group);
for (SPELL_ASPECT g : SPELL_ASPECT.values()) {
if (!aspects.contains(g)) {
if (new ArrayList<>(Arrays.asList(g.groups)).contains(spell.getSpellGroup())) {
aspects.add(g);
}
}
}
}
return spell_groups.size() > 8 ? aspects.stream().map(el -> createNodeBranch(new RadialSpellAspect(el), source, target)).collect(Collectors.toList()) : spell_groups.stream().map(el -> createNodeBranch(new RadialSpellGroup(el), source, target)).collect(Collectors.toList());
}
use of eidolons.entity.active.DC_SpellObj in project Eidolons by IDemiurge.
the class DivinationMaster method tryDivine.
private static DC_SpellObj tryDivine() {
DC_SpellObj spell = null;
for (ObjType spellType : spellPool) {
if (!checkSpell(spellType)) {
continue;
}
spell = LibraryManager.getSpellFromHero(hero, spellType.getName());
if (spell == null) {
spell = new DC_SpellObj(spellType, hero.getOwner(), hero.getGame(), hero.getRef());
hero.getSpells().add(spell);
if (LibraryManager.checkHeroHasSpell(hero, spellType)) {
applyKnownSpellDivinationEffect(spell);
}
} else {
if (!spell.getGame().isSimulation()) {
applyKnownSpellDivinationEffect(spell);
}
}
pool -= spell.getIntParam(PARAMS.SPELL_DIFFICULTY);
spell.setProperty(G_PROPS.SPELL_POOL, SpellEnums.SPELL_POOL.DIVINED.toString());
hero.addProperty(PROPS.DIVINED_SPELLS, spell.getName());
return spell;
}
return spell;
}
use of eidolons.entity.active.DC_SpellObj in project Eidolons by IDemiurge.
the class LibraryManager method hasSpellVersion.
public static boolean hasSpellVersion(Unit hero, Entity type, PROPERTY poolProp, boolean replace) {
hero.initSpells(true);
boolean upgrade = type.isUpgrade();
String baseName = (upgrade) ? type.getProperty(G_PROPS.BASE_TYPE) : type.getName();
for (DC_SpellObj spell : hero.getSpells()) {
if (StringMaster.compare(spell.getSpellPool() + "", poolProp.getName(), false)) {
if (spell.isUpgrade()) {
if (spell.getProperty(G_PROPS.BASE_TYPE).equalsIgnoreCase(baseName)) {
if (replace) {
replaceSpell(hero, type, poolProp, spell);
}
return true;
}
} else if (spell.getName().equalsIgnoreCase(baseName)) {
if (replace) {
replaceSpell(hero, type, poolProp, spell);
}
return true;
}
}
}
return false;
}
use of eidolons.entity.active.DC_SpellObj in project Eidolons by IDemiurge.
the class PriorityManagerImpl method getAttackPriority.
@Override
public int getAttackPriority(DC_ActiveObj active, BattleFieldObject targetObj) {
if (getUnit().getBehaviorMode() != AiEnums.BEHAVIOR_MODE.BERSERK && getUnit().getBehaviorMode() != AiEnums.BEHAVIOR_MODE.CONFUSED) {
if (targetObj.isOwnedBy(active.getOwnerObj().getOwner())) {
return -10000;
}
}
boolean attack = !(active instanceof DC_SpellObj);
int enemy_priority = getUnitPriority(targetObj);
int priority = enemy_priority;
int damage_priority = getDamagePriority(active, targetObj, attack);
if (active.isThrow()) {
if (damage_priority < getUnitPriority(targetObj) * 2) {
// TODO
return -1;
}
}
// getActionNumberFactor
int counter_penalty = 0;
if (active.getActionGroup() != ActionEnums.ACTION_TYPE_GROUPS.ATTACK) {
// if (AttackOfOpportunityRule.checkAction(active)) {
// counter_penalty = getAttackOfOpportunityPenalty(active,
// targetObj);
// }
} else {
if (!active.isRanged() && targetObj.canCounter() && !getUnit().checkPassive(UnitEnums.STANDARD_PASSIVES.NO_RETALIATION) && !active.checkProperty(G_PROPS.STANDARD_PASSIVES, UnitEnums.STANDARD_PASSIVES.NO_RETALIATION.getName())) {
if ((damage_priority != getLethalDamagePriority() && damage_priority != getUnconsciousDamagePriority()) || targetObj.checkPassive(UnitEnums.STANDARD_PASSIVES.FIRST_STRIKE)) {
counter_penalty = getCounterPenalty(active, (Unit) targetObj);
}
}
}
// TODO spells!
if (active instanceof DC_SpellObj) {
// check mod effects too
Action action = AiActionFactory.newAction(active, new Context(getUnit(), targetObj));
damage_priority += getSpellPriority(GOAL_TYPE.DEBILITATE, action);
damage_priority += getSpellPriority(GOAL_TYPE.DEBUFF, action);
if (getUnit().getAiType().isCaster()) {
damage_priority *= 4;
}
} else {
if (active.isRanged()) {
if (getUnit().getAiType() == AiEnums.AI_TYPE.ARCHER) {
damage_priority *= 2;
}
} else if (getUnit().getAiType() == AiEnums.AI_TYPE.BRUTE) {
damage_priority *= 2;
}
}
damage_priority = Math.max(getConstInt(AiConst.DAMAGE_PERCENTAGE_MOD_MINIMUM), damage_priority - counter_penalty);
priority = priority * damage_priority / 100;
priority += getConstInt((active instanceof DC_SpellObj) ? AiConst.DEFAULT_SPELL_ATTACK_PRIORITY : AiConst.DEFAULT_ATTACK_PRIORITY);
if (active.isThrow()) {
try {
applyThrowPenalty(active);
priority = this.priority;
} catch (Exception e) {
main.system.ExceptionMaster.printStackTrace(e);
addMultiplier(-50, "throw");
}
}
if (targetObj.isNeutral()) {
addMultiplier(-90, "Neutral");
}
return priority;
}
use of eidolons.entity.active.DC_SpellObj in project Eidolons by IDemiurge.
the class PruneMaster method pruneTargetsForAction.
public void pruneTargetsForAction(List<? extends DC_Obj> targets, GOAL_TYPE goal, UnitAI ai, DC_ActiveObj action) {
/*
* cache for each goal?
*
* the 'pruneSize' must be a minimum of targets to prune... and beyond
* that, there should be some default prune logic
*/
for (DC_Obj e : targets) {
if (!(e instanceof Unit)) {
// another method?
return;
}
}
int size = targets.size();
// getPruneSize(goal);
int toPrune = size - 1;
if (// this is only the max size, how to ensure pruning of
toPrune <= 0) // 'valid' targets too?
{
if (action.isRanged() || action instanceof DC_SpellObj) {
// TODO sometimes it's not the size, but the distance!
return;
}
}
// for melee...
Boolean byCapacity = true;
Boolean byHealth = true;
Boolean byDistance = true;
Boolean byDanger = false;
Boolean byPower = true;
Boolean byType = false;
switch(goal) {
case RESTORE:
byHealth = false;
break;
case ATTACK:
byHealth = false;
byDanger = true;
break;
case BUFF:
// TODO ignore near-dead and 'surrounded'
byDanger = true;
// enemies ready to fall
break;
case CUSTOM_HOSTILE:
case CUSTOM_SUPPORT:
}
Boolean enemy = GoalManager.isGoalVsEnemies(goal);
int minDistance = // TODO for ALLIES?
getAnalyzer().getClosestEnemyDistance(ai.getUnit());
List<DC_Obj> pruneList = new ArrayList<>();
// TODO sort() first? to be sure to cut off the tail...
int maxPower = ParamAnalyzer.getMaxParam(PARAMS.POWER, new ArrayList<>(targets));
int limit = 0;
boolean first = true;
pruneLoop: while ((first || pruneList.size() < toPrune) && limit < 5) {
first = false;
for (DC_Obj t : targets) {
if (pruneList.contains(t)) {
continue;
}
boolean result = false;
while (true) {
if (byDistance) {
int distance = PositionMaster.getDistance(t, ai.getUnit());
// if (distance < minDistance) {
// minDistance = distance;
// } else {
result = (getDistancePruneFactor(limit, t, ai, action)) < distance - minDistance;
// }
if (result) {
break;
}
}
if (byCapacity) {
float capacity = DC_PriorityManager.getCapacity((Unit) t);
if (result) {
break;
}
}
if (byHealth) {
// ?
int health = DC_PriorityManager.getHealthFactor(t, byHealth);
result = (health < getHeathPruneFactor(limit, t, ai, action));
if (result) {
break;
}
}
if (byPower) {
result = t.getIntParam(PARAMS.POWER) * 100 / maxPower < getPowerFactor(limit, ai, action);
if (result) {
break;
}
}
// by danger
break;
}
if (result) {
pruneList.add(t);
continue pruneLoop;
}
}
// if nobody was pruned, increase limits
limit++;
}
main.system.auxiliary.log.LogMaster.log(LOG_CHANNEL.AI_DEBUG, "PRUNING FOR " + action + " : " + pruneList);
for (DC_Obj t : pruneList) {
targets.remove(t);
}
}
Aggregations