// Calculates the accuracy between the two units public static float calculateAccuracy(ref Unit attacker, ref Unit defender, ref BattleMap map) { // Variables int adjacentAlliesAttacker= map.findAllies(defender.mapPos[0], defender.mapPos[1], 1, 1, map.getTeamID(attacker.mapPos)).size; int adjacentAlliesDefender= map.findAllies(attacker.mapPos[0], attacker.mapPos[1], 1, 1, map.getTeamID(defender.mapPos)).size; int distance= (defender.level-attacker.level); return MathHelper.Clamp((100f-2f*distance-4*adjacentAlliesDefender+4*adjacentAlliesAttacker)/100f, 0f, 1f); }
// --- Methods --- // Activates the trap on the given victim. Returns if actually activated or not public bool activate(ref Unit victim, ref BattleMap map) { if(teamID== map.getTeamID(victim.mapPos)) return false; if(trapEvent== null) return false; return trapEvent(ref victim, victim.mapPos[0], victim.mapPos[1], this, ref map, ref parent); }
// Called before the unit is updating the stat effects to see if it will update public virtual bool onPreUpdateStatEffect(ref StatEffect statEffect, ref BattleMap map) { return prof.onPreUpdateStatEffect( this, ((map.isUnitNearbyWithPassive(mapPos[0], mapPos[1], map.getTeamID(mapPos), "lamb\'s_blood", 2)) ? (Start.rng.Next(0, 5)>= 2) : true ), ref statEffect, ref map ); }
// --- Methods --- // Gives buffs to every ally around you know whatever private void giveBuff(ref Unit unit, ref BattleMap map) { // Variables List<int[]> allies= map.findAllies(unit.mapPos[0], unit.mapPos[1], 1, 3, map.getTeamID(unit.mapPos)); for(int i= 0; i< allies.size; i++) { map.teams.items[allies.items[i][0]].units.items[allies.items[i][1]].addStatEffect( new StatEffect( EffectType.Buff, "Morale Boost", "+4 to all stats", buffSE, 1 ), ref map ); } }
// Moves the unit public virtual void ai_moveUnit(Unit unit, BattleMap map, int[] spotToMoveTo, bool isUncontrollable) { map.walkSearch(unit.mapPos[0], unit.mapPos[1], unit.move, ((isUncontrollable) ? -1 :map.getTeamID(unit.mapPos))); System.Threading.Thread.Sleep(1000); map.moveUnit(map.getFullUnitID(unit.mapPos), spotToMoveTo[0], spotToMoveTo[1]); }
// Gets the target public virtual void ai_getTarget(Unit unit, BattleMap map, bool isUncontrollable, out int[] target, out int[] spotToMoveTo, out AttackInfo info) { info= new AttackInfo(); info.range= new int[] {1, 1}; map.aiSearch(unit.mapPos[0], unit.mapPos[1], unit.move, info.range[1], isUncontrollable, map.getTeamID(unit.mapPos), info); spotToMoveTo= map.findAISpot(unit.mapPos[0], unit.mapPos[1], info.range, map.aggressiveAI); target= map.tiles.items[spotToMoveTo[0], spotToMoveTo[1]].t; info= AttackInfo.createBasicAttack(map.getFullUnitID(unit.mapPos), target, ref map); }
// Updates the ai normally public virtual void updateAINormal(Unit unit, BattleMap map) { // Variables int[] spot; int[] target= map.getClosestEnemy(unit.mapPos[0], unit.mapPos[1], map.getTeamID(unit.mapPos)); AttackInfo info= AttackInfo.createBasicAttack(map.getFullUnitID(unit.mapPos), target, ref map); int heuristic; // Get Target info.range= new int[] {1, 1}; map.aiSearch(unit.mapPos[0], unit.mapPos[1], unit.move, info.range[1], false, map.getTeamID(unit.mapPos), info, target); spot= map.findAISpot(unit.mapPos[0], unit.mapPos[1], info.range, map.aggressiveAI); if(!unit.isWalkingDone) { ai_moveUnit(unit, map, spot, false); map.destroyPaths(); map.endUnitWalking(map.getFullUnitID(unit.mapPos)); if(unit.isTurnEnded) return; } heuristic= map.getHeuristic(unit.mapPos, map.getUnitXY(target)); if(!unit.isAttackingDone && heuristic>= info.range[0] && heuristic<= info.range[1]) { ai_attackUnit(unit, map, info, false); map.destroyPaths(); map.endUnitAttacking(map.getFullUnitID(unit.mapPos)); if(unit.isTurnEnded) return; } }
// Stat effect when the unit uses Rally Spirit private void powerInNumbersSE(ref Unit unit, ref BattleMap map) { // Variables int amount= (2*(map.findAllies(unit.mapPos[0], unit.mapPos[1], 0, 2, map.getTeamID(unit.mapPos))).size); unit.defense+= amount; unit.resistance+= amount; }
// --- Inherited Methods --- // Called when the unit is healing another unit public override int onHealing(Profession prof, ref Unit unit, int health, int amount, ref Unit target, ref BattleMap map) { if(map.getTeamID(unit.mapPos)== map.getTeamID(target.mapPos)) { if(Start.rng.Next(0, 10)< 2) unit.clearDebuffs(); } return amount; }
// Makes the unit attack the given unit, given that unit's coords on the map, the name of the attack, and a reference to the map public override bool attackUnit(Unit unit, bool initiatedAttack, ref Unit victim, int x, int y, ref AttackInfo info, ref BattleMap map) { switch(info.skillID) { case "smite": case "basic_attack": { if(victim== null) return false; victim.takeDamage(ref info, ref unit, ref map); if(!info.missed && unit.isAlive && !unit.isAI) unit.gainExp(ref victim, ref map); };break; case "multicure": { // Variables List<int[]> allies= map.findAllies(unit.mapPos[0], unit.mapPos[1], 1, 2, map.getTeamID(unit.mapPos)); for(int i= 0; i< allies.size; i++) map.teams.items[allies.items[i][0]].units.items[allies.items[i][1]].heal(-1*info.damage, ref unit, ref map); if(unit.isAlive && !unit.isAI) unit.gainExp(64*allies.size, ref map); };break; case "armor_of_god": { if(victim== null) return false; unit.addStatEffect( new StatEffect( EffectType.Buff, "Armor of God", "+35 Def and Res", armorOfGodSE, 2 ), ref map ); if(unit.isAlive && !unit.isAI) unit.gainExp(ref victim, ref map); };break; case "rally_spirit": { // Variables List<int[]> allies= map.findAllies(unit.mapPos[0], unit.mapPos[1], 0, 2, map.getTeamID(unit.mapPos)); for(int i= 0; i< allies.size; i++) { map.teams.items[allies.items[i][0]].units.items[allies.items[i][1]].addStatEffect( new StatEffect( EffectType.Buff, "Rally Spirit", "+10% to all stats", rallySpiritSE, 3 ), ref map ); } if(!info.missed && unit.isAlive && !unit.isAI) unit.gainExp(32*allies.size, ref map); };break; case "rejuvinate": { if(victim== null) return false; if(victim.getStatusEffect()== null) victim.clearDebuffs(); else { if(!victim.clearStatusEffect()) info.missed= false; } if(!info.missed && unit.isAlive && !unit.isAI) unit.gainExp(ref victim, ref map); };break; case "healing_prayer": { // Variables List<int[]> allies= map.findAllAllies(map.getTeamID(unit.mapPos)); for(int i= 0; i< allies.size; i++) { map.teams.items[allies.items[i][0]].units.items[allies.items[i][1]].heal( map.teams.items[allies.items[i][0]].units.items[allies.items[i][1]].originalHealth, ref unit, ref map ); } unit.addStatEffect( new StatEffect( EffectType.Debuff, "Humility", "-75% to all stats", healingPrayerSE, 2 ), ref map ); if(unit.isAlive && !unit.isAI) unit.gainExp(256*allies.size, ref map); };break; case "mend": { if(victim== null) return false; victim.heal(-1*info.damage, ref unit, ref map); if(unit.isAlive && !unit.isAI) unit.gainExp(ref victim, ref map); };break; case "prophetic_reap": { if(activatedPropheticReap) return false; activatedPropheticReap= true; unit.addStatEffect( new StatEffect( EffectType.Buff, "Prophetic Prayer", "Deal "+((float)(unit.magic)/7f)+" damage to all enemies once dissipated", propheticReapSE, 3 ), ref map ); };break; case "banish_spirits": { if(victim== null) return false; victim.addStatEffect( new StatEffect( EffectType.Buff, "Banish Spirits", "+10% Atk", positiveBanishSpiritsSE, 3 ), ref map ); victim.addStatEffect( new StatEffect( EffectType.Debuff, "Banish Spirits", "-15% Def and Res", negativeBanishSpiritsSE, 3 ), ref map ); victim.addStatEffect( StatEffect.create(StatusEffect.Enraged, 3), ref map ); };break; case "rest_in_god": { if(victim== null) return false; victim.addStatEffect( new StatEffect( EffectType.Buff, "God\'s Blessing", "+20 to all stats", restInGodSE, 1 ), ref map ); map.endUnitWalking(map.getFullUnitID(unit.mapPos)); };break; } return true; }
// Shows the player if he/she should attack public override AttackInfo showAttackDecision(string skillID, Unit unit, ref Unit defender, ref BattleMap map) { if(skillID== "basic_attack") return AttackInfo.createBasicAttack(map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map); // Variables AttackInfo info= AttackInfo.create(skillID, map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map); switch(skillID) { case "multicure": info.damage= -1*getLargest(roundUp((float)(unit.level)/2f), roundUp((float)(unit.magic)/3f), 10); info.projDefenderStats[0]-= info.damage; if(hasPassive("mana_restoration")) info.projDefenderStats[1]+= (info.damage/2); break; case "armor_of_god": info.projDefenderStats[3]+= 35; info.projDefenderStats[5]+= 35; break; case "smite": info.damage= info.calculateDamage(ref map); info.damage+= (int)(Math.Max(0.25f*unit.resistance-0.25f*defender.resistance, 0f)); info.projDefenderStats[0]-= info.damage; break; case "rally_spirit": case "rejuvinate": case "prophetic_reap": info.accuracy= 1f; info.criticalChance= 0f; break; case "healing_prayer": if(hasPassive("mana_restoration")) info.projDefenderStats[1]+= (info.damage/2); info.accuracy= 1f; info.criticalChance= 0f; break; case "mend": info.damage= ((hasPassive("evil\'s_bane") && map.getTeamID(unit.mapPos)!= map.getTeamID(defender.mapPos)) ? 1 : -1)*getLargest(2*unit.level, roundUp((float)(unit.magic)/2f), 15); info.damage+= (4*(map.findAllies(unit.mapPos[0], unit.mapPos[1], 0, 2, map.getTeamID(unit.mapPos))).size); info.projDefenderStats[0]-= info.damage; if(hasPassive("mana_restoration")) info.projDefenderStats[1]+= (info.damage/2); info.criticalChance= 0f; break; case "banish_spirits": info.projDefenderStats[2]= (int)(info.projDefenderStats[2]*1.1f); info.projDefenderStats[3]= (int)(info.projDefenderStats[3]*0.85f); info.projDefenderStats[5]= (int)(info.projDefenderStats[5]*0.85f); break; case "rest_in_god": info.projDefenderStats[2]+= 20; info.projDefenderStats[3]+= 20; info.projDefenderStats[4]+= 20; info.projDefenderStats[5]+= 20; info.projDefenderStats[6]+= 20; break; } return info; }
// Called when the unit has just finished with a stat effect public override void onDoneWithStatEffect(Unit unit, ref StatEffect statEffect, ref BattleMap map) { if(statEffect.name== "Prophetic Prayer") { // Variables List<int[]> enemies= map.findAllEnemies(map.getTeamID(unit.mapPos)); AttackInfo info; int[] unitID= map.getFullUnitID(unit.mapPos); for(int i= 0; i< enemies.size; i++) { info= AttackInfo.create("prophetic_reap", unitID, enemies.items[i], ref map); info.damage= (int)((float)(unit.magic)/7f); info.accuracy= 1f; info.criticalChance= 0f; map.teams.items[enemies.items[i][0]].units.items[enemies.items[i][1]].takeDamage(ref info, ref unit, ref map); } activatedPropheticReap= false; } base.onDoneWithStatEffect(unit, ref statEffect, ref map); }