예제 #1
0
 // Attacks the unit
 public virtual void ai_attackUnit(Unit unit, BattleMap map, AttackInfo info, bool isUncontrollable)
 {
     map.attackSearch(unit.mapPos[0], unit.mapPos[1], info.range[0], info.range[1]);
     System.Threading.Thread.Sleep(1000);
     map.gstate.attackDecisionGui.open(ref info);
     System.Threading.Thread.Sleep(2500);
     game.gui.close("attack_decision");
     map.gstate.stage=	0;
     map.makeUnitAttack(map.getFullUnitID(unit.mapPos), map.getUnitX(info.defenderID), map.getUnitY(info.defenderID), ref info);
 }
예제 #2
0
        // Takes the given amount of damage
        public virtual int takeDamage(ref AttackInfo info, ref Unit instigator, ref BattleMap map)
        {
            // Variables
            int	oldHealth=	health;
            int	amount=	info.damage;

            if((float)(Start.rng.NextDouble())<= info.accuracy)
            {
                amount=	instigator.onDealtDamage(health, amount, this, ref map);
                if((float)(Start.rng.NextDouble())<= info.criticalChance)
                {
                    // Animate Critical
                    Console.WriteLine("Critical Hit!");
                    info.criticalHit=	true;
                    amount=	instigator.onCriticalHit(health, amount, this, ref map);
                    amount=	onHitByCritical(health, amount, this, ref map);
                }
                else
                {
                    // Animate regular
                }
                amount=	onTakeDamage(oldHealth, health, amount, ref instigator, ref map);
                health-=	amount;
            }
            else
            {
                Console.WriteLine("Missed!");
                // Animate Miss
                info.missed=	true;
                onDodgedAttack(amount, ref instigator, ref map);
                instigator.onMissedAttack(amount, this, ref map);
            }
            if(health== 0)
                map.removeUnit(map.getFullUnitID(mapPos));

            return health;
        }
예제 #3
0
        // 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")
            {
                // Variables
                AttackInfo	infoba=	AttackInfo.createBasicAttack(map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map);

                infoba.projAttackerStats[1]=	0;

                return infoba;
            }

            // Variables
            AttackInfo	info=	AttackInfo.create(skillID, map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map);
            float	tsDmg=	((hasPassive("tiger_stance") && ((float)(unit.mana)/(float)(unit.originalMana))> 0.5f) ? 0.2f : 0f);

            if(!hasPassive("lion_stance") || Start.rng.Next(0, 20)>= 3)
                info.projAttackerStats[1]=	0;
            if(hasPassive("cobra_stance"))
                info.criticalChance=	Math.Max(info.criticalChance+0.15f, 1f);
            switch(skillID)
            {
                case "precise_strike":
                    if(isSkillHoned)
                    {
                        unit.attack=	(int)(1.25f*unit.attack);
                        info.criticalChance=	Math.Max(1.15f*info.criticalChance, 1f);
                        isSkillHoned=	false;
                    }

                    if(((float)(unit.mana)/(float)(unit.originalMana))> 0.5f)
                    {
                        info.damage=	info.calculateDamage(1.15f+tsDmg, 0f, 1f, 1f, ref map);
                        info.projDefenderStats[0]-=	info.damage;
                        info.accuracy=	1f;
                    }
                    else
                        info.damage=	info.calculateDamage(0.95f, 0f, 1f, 1f, ref map);
                    break;

                case "sun\'s_might":
                    if(isSkillHoned)
                    {
                        unit.attack=	(int)(1.25f*unit.attack);
                        info.criticalChance=	Math.Max(1.15f*info.criticalChance, 1f);
                        isSkillHoned=	false;
                    }

                    info.damage=	info.calculateDamage(1f+tsDmg, 0f, 1f, 1f, ref map);
                    info.projAttackerStats[0]=	Math.Max(info.projAttackerStats[0]+(int)(0.15f*info.damage), unit.originalHealth);
                    info.projAttackerStats[1]=	Math.Max(info.projAttackerStats[1]+(int)(0.15f*info.damage), unit.originalMana);
                    info.projDefenderStats[0]-=	info.damage;
                    break;

                case "meditation":
                    info.projAttackerStats[0]=	Math.Max(info.projAttackerStats[0]+(int)(0.1f*unit.originalHealth), unit.originalHealth);
                    info.projAttackerStats[1]=	Math.Max(info.projAttackerStats[1]+(int)(0.1f*unit.originalMana), unit.originalMana);
                    info.projAttackerStats[2]=	(int)(1.05f*info.projAttackerStats[2]);
                    info.projAttackerStats[1]=	info.attackerStats[1];
                    break;

                case "serpent\'s_sting":
                    if(isSkillHoned)
                    {
                        unit.attack=	(int)(1.25f*unit.attack);
                        info.criticalChance=	Math.Max(1.15f*info.criticalChance, 1f);
                        isSkillHoned=	false;
                    }

                    info.damage=	info.calculateDamage(1f+tsDmg, 0f, 0.8f, 1f, ref map);
                    info.projDefenderStats[0]-=	info.damage;
                    if(((float)(unit.mana)/(float)(unit.originalMana))< 0.5f)
                        info.accuracy=	Math.Max(info.accuracy-0.2f, 0f);
                    break;

                case "hone_skill":
                    info.projAttackerStats[1]=	info.attackerStats[1];
                    break;

                case "vigilant_strike":
                    if(isSkillHoned)
                    {
                        unit.attack=	(int)(1.25f*unit.attack);
                        info.criticalChance=	Math.Max(1.15f*info.criticalChance, 1f);
                        isSkillHoned=	false;
                    }

                    info.damage=	info.calculateDamage(1.5f+tsDmg, 0f, 1f, 1f, ref map);
                    info.projDefenderStats[0]-=	info.damage;
                    break;

                case "lethal_strike":
                    if(isSkillHoned)
                    {
                        unit.attack=	(int)(1.25f*unit.attack);
                        info.criticalChance=	Math.Max(1.15f*info.criticalChance, 1f);
                        isSkillHoned=	false;
                    }

                    info.damage=	info.defenderStats[0];
                    info.projDefenderStats[0]=	0;
                    info.accuracy=	0.22f;
                    break;
            }

            return info;
        }
예제 #4
0
 // 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]);
 }
예제 #5
0
        // 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);
        }
예제 #6
0
        // 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;
            }
        }
예제 #7
0
 // Shows the player if he/she should attack
 public virtual AttackInfo showAttackDecision(string skillID, Unit unit, ref Unit defender, ref BattleMap map)
 {
     return AttackInfo.createBasicAttack(map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map);
 }
예제 #8
0
        // 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 base.showAttackDecision(skillID, unit, ref defender, ref map);

            // Variables
            AttackInfo	info=	AttackInfo.create(skillID, map.getFullUnitID(unit.mapPos), map.getFullUnitID(defender.mapPos), ref map);

            if(hasPassive("critical_rage"))
                info.criticalChance=	Math.Max(info.criticalChance+0.05f, 1f);
            switch(skillID)
            {
                case "enrage":
                    info.accuracy=	1f;
                    info.criticalChance=	0f;
                    info.projAttackerStats[2]=	(int)(info.projAttackerStats[2]*1.25f+4f);
                    info.projAttackerStats[2]=	(int)(info.projAttackerStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.80f);

                    info.projDefenderStats[2]=	(int)(info.projDefenderStats[2]*1.25f+4f);
                    info.projDefenderStats[2]=	(int)(info.projDefenderStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    info.projDefenderStats[3]=	(int)(info.projDefenderStats[3]*0.80f);
                    break;

                case "furious_slash":
                    info.damage=	info.calculateDamage(1.1f, 0f, 1f, 1f, ref map);
                    info.projAttackerStats[2]=	(int)(info.projAttackerStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.80f);
                    info.projDefenderStats[0]-=	info.damage;
                    break;

                case "let_loose":
                    info.damage=	info.calculateDamage(ref map);
                    if(defender.getDefensePerc()== 0f)
                        info.damage+=	(int)(unit.defense*0.5f);
                    else
                        info.damage+=	Math.Max((int)(unit.defense*0.5f-defender.defense*defender.getDefensePerc()*0.5f), 4);
                    info.projDefenderStats[0]-=	info.damage;
                    info.projAttackerStats[2]=	(int)(info.projAttackerStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.80f);
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.75f);
                    info.criticalChance=	0f;
                    break;

                case "intimidate":
                    info.projDefenderStats[2]=	(int)(info.projDefenderStats[2]*0.88f);
                    info.projDefenderStats[3]=	(int)(info.projDefenderStats[3]*0.88f);
                    info.projDefenderStats[5]=	(int)(info.projDefenderStats[5]*0.88f);
                    info.criticalChance=	0f;
                    break;

                case "stockpile_rage":
                    info.accuracy=	1f;
                    info.criticalChance=	0f;
                    break;

                case "suicidal_slash":
                    info.damage=	info.calculateDamage(1.2f, 0f, 1f, 1f, ref map);
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.96f);
                    info.projDefenderStats[0]-=	info.damage;
                    break;

                case "piercing_jab":
                    info.damage=	info.calculateDamage(1f, 0f, 0.5f, 1f, ref map);
                    info.projDefenderStats[0]-=	info.damage;
                    info.accuracy=	Math.Max(info.accuracy-0.2f, 0f);
                    break;

                case "counter_swipe":
                    info.damage=	info.calculateDamage(0.75f, 0f, 1f, 1f, ref map);
                    if(defender.getDefensePerc()== 0f)
                        info.damage+=	(int)(defender.attack*0.25f);
                    else
                        info.damage+=	Math.Max((int)(defender.attack*0.25f-defender.defense*defender.getDefensePerc()), 4);
                    info.projDefenderStats[0]-=	info.damage;
                    break;

                case "fury_swipes":
                    info.damage=	info.calculateDamage(0.5f, 0f, 1f, 1f, ref map);
                    info.damage*=	3;
                    info.projDefenderStats[0]-=	info.damage;
                    break;
                case "raging_battlecry":
                    info.projAttackerStats[2]=	(int)(info.projAttackerStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    info.projAttackerStats[3]=	(int)(info.projAttackerStats[3]*0.80f);

                    if(info.attackerID== info.defenderID)
                        info.projDefenderStats[2]=	(int)(info.projDefenderStats[2]*(1.25f+stockpiled+((hasPassive("adrenaline_rush")) ? 0.1f : 0f)));
                    else
                        info.projDefenderStats[2]=	(int)(info.projDefenderStats[2]*1.25f);
                    info.projDefenderStats[3]=	(int)(info.projDefenderStats[3]*0.80f);
                    break;
            }

            return info;
        }
예제 #9
0
        // 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;
        }
예제 #10
0
        // 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;
        }
예제 #11
0
        // 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);
        }