public override CombatResults CalculateResults(StatsPackage caster, StatsPackage target) { CombatResults results = DoesAttackHit(caster, target); if (!results.DidMiss && !results.DidAvoid) { int damage = 100; if (Engine.RNG.Next(0, 100) <= 10) { damage *= 2; results.DidCrit = true; } results.PureDamage = damage; results.AbsorbedDamage = CalculateAbsorption(damage, target); results.AppliedDamage = results.PureDamage - results.AbsorbedDamage; results.ReflectedDamage = CalculateReflectedDamage(results.AppliedDamage, target); if (!target.HasEffect("Ignite")) { int result = Engine.RNG.Next(0, 100); if (result <= 15) { target.ApplyEffect(new Core.Stats.Classes.Mage.Effect_FireballDOT(target)); } } } return(results); }
/// <summary> /// Shows projected losses for attacking and defending units.</summary> /// <param name="target"> /// The coordinates of the <see cref="Site"/> that is the target of the attack.</param> /// <remarks><para> /// <b>ShowLosses</b> invokes <see cref="Unit.EstimateLosses"/> with all selected units and /// updates the "Projected Losses" message with the resulting percentage losses. /// </para><para> /// <b>ShowLosses</b> shows two zeroes if no units are selected, and a notification if the /// specified <paramref name="target"/> is an invalid map location.</para></remarks> private void ShowLosses(PointI target) { // show notification for invalid selection if (!this._mapView.InSelectedRegion(target)) { LossesInfo.Visibility = Visibility.Collapsed; LossesInfoNone.Visibility = Visibility.Visible; return; } CombatResults results = new CombatResults(); LossesInfo.Visibility = Visibility.Visible; LossesInfoNone.Visibility = Visibility.Collapsed; // compute estimated combat losses if (this._selected.Count > 0) { Unit unit = (Unit)this._selected[0]; results = unit.EstimateLosses( Session.Instance.WorldState, this._selected, target, true); } // show attacker & defender losses LossesInfo.Content = String.Format(ApplicationInfo.Culture, this._lossesFormat, results.AttackerPercent, results.DefenderPercent); }
public CombatResults attemptDamage(int damage, int atkStat, int critBonusRoll) { CombatResults retval = new CombatResults(); int dRoll = D.R20(); if (dRoll == 1) { retval.miss = true; return(retval); } int atkRoll = atkStat + dRoll; Debug.Log("Attack Roll: " + atkRoll); if (atkRoll > character.stats.agility || dRoll == 20) { bool crit = D.R20() >= 20 - critBonusRoll; //if(log) // CombatLogger.instance.logCombatString(attacker, character, ability, false, damage, crit); retval.crit = crit; Debug.Log("Hit"); return(retval); } //CombatLogger.instance.logCombatString(attacker, character, ability, true, 0, false); retval.miss = true; Debug.Log("Miss"); return(retval); }
// Update is called once per frame void Update() { if (runCombat == true) { cam1.enabled = false; cam2.enabled = true; CombatStack = combatCalc(attackingUnit, attackerTerrain, defendingUnit, defenderTerrain); attackingUnit = attackerTerrain = defendingUnit = defenderTerrain = null; playAnime = true; runCombat = false; } if (playAnime) { playAnimation(CombatStack); } if (Time.time >= timeStamp[3] && timeStamp[3] != 0) { cam1.enabled = true; cam2.enabled = false; timeStamp[0] = timeStamp[1] = timeStamp[2] = timeStamp[3] = 0; playAnime = false; } }
public override CombatResults CalculateResults(StatsPackage caster, StatsPackage target) { CombatResults results = DoesAttackHit(caster, target); if (!results.DidMiss && !results.DidAvoid) { int damage = (int)((caster.SpellPower.EffectiveValue * 0.5) + (caster.AttackPower.EffectiveValue * 0.5)); if (DoesAttackCrit(caster)) { damage = ApplyCriticalDamage(damage, caster); results.DidCrit = true; } results.PureDamage = damage; results.AbsorbedDamage = CalculateAbsorption(damage, target); results.AppliedDamage = results.PureDamage - results.AbsorbedDamage; results.ReflectedDamage = CalculateReflectedDamage(results.AppliedDamage, target); if (!target.HasEffect(typeof(Effect_FireLashDOT))) { target.ApplyEffect(new Effect_FireLashDOT()); } } return(results); }
public override void useAbilty(Character target) { base.useAbilty(target); int damage = getRoundedDamage(damagerPerStrength, character.stats.strength); int timesHit = 0; int totalDamage = 0; CombatResults results = target.health.attemptDamage(damage, character.stats.strength, character.stats.critBonusRoll); if (!results.miss) { int usedDamage = results.crit ? damage * 2 : damage; target.health.takeDamage(usedDamage); timesHit++; totalDamage += usedDamage; } results = target.health.attemptDamage(damage, character.stats.strength, character.stats.critBonusRoll); if (!results.miss) { int usedDamage = results.crit ? damage * 2 : damage; target.health.takeDamage(usedDamage); timesHit++; totalDamage += usedDamage; } sendCombatLog(results, target, totalDamage, timesHit); }
public static void OnDefend(CombatResults results) { for (int i = 0; i < equippedItems.Count; i++) { equippedItems[i].OnDefend(results); } }
public override CombatResults CalculateResults(StatsPackage caster, StatsPackage target) { CombatResults results = DoesAttackHit(caster, target); if (!results.DidMiss && !results.DidAvoid) { int damage = (int)(caster.SpellPower.EffectiveValue * 1.5); if (DoesAttackCrit(caster)) { damage = ApplyCriticalDamage(damage, caster); results.DidCrit = true; } results.PureDamage = damage; results.AbsorbedDamage = CalculateAbsorption(damage, target); results.AppliedDamage = results.PureDamage - results.AbsorbedDamage; results.ReflectedDamage = CalculateReflectedDamage(results.AppliedDamage, target); if (!target.HasEffect("Ignite")) { int result = Engine.RNG.Next(0, 100); if (result <= 20) { target.ApplyEffect(new Effect_FireballDOT(target)); } } } return(results); }
public virtual void OnAttack(CombatResults results) { for (int i = 0; i < appliedEffects.Count; i++) { appliedEffects[i].OnAttack(results); } }
public override void DoMove(Point deltaMove, bool noMove) { Point locationAfterMove = Game.Dungeon.Player.LocationMap + deltaMove; //Attack the monster in its square with bonuses //Bonus to hit and damage Game.MessageQueue.AddMessage("CloseQuarters!"); CombatResults results = Game.Dungeon.Player.AttackMonsterWithModifiers(target, noCardinals, 0, noCardinals, 0, true); Screen.Instance.DrawMeleeAttack(Game.Dungeon.Player, target, results); moveCounter = 0; //Standard move into square, copied from PCMove bool okToMoveIntoSquare = false; if (results == CombatResults.DefenderDied) { okToMoveIntoSquare = true; } if (okToMoveIntoSquare) { Game.Dungeon.MovePCAbsoluteSameLevel(locationAfterMove.x, locationAfterMove.y); } }
public override void OnAttack(CombatResults results) { if (parent == results.Target && results.DidCrit) //IF WE GOT CRITTED { } base.OnAttack(results); }
public override CombatResults CalculateResults(Stats.StatsPackage caster, Stats.StatsPackage target) { results = new CombatResults() { Caster = caster, Target = target, UsedAbility = this }; caster.ApplyEffect(new Effects.ShieldWall(caster)); return(results); }
public override void OnDefend(CombatResults results) { if (results.DidCrit) { addCritBonus(5); } base.OnDefend(results); }
public static void PerformAbility(StatsPackage caster, StatsPackage target, Ability ability) { CombatResults combatResults = ability.CastAbilityTarget(caster, target); caster.OnAttack(combatResults); target.OnDefend(combatResults); combatResults.ProcessResults(); }
public override void DoMove(Point deltaMove, bool noMove) { Point locationAfterMove = Game.Dungeon.Player.LocationMap + deltaMove; //Attack the monster in its square with bonuses //Bonus depends on moveNumber int bonus = moveCounter - 1; //After 5 the bonus doesn't get any higher if (bonus > 4) { bonus = 4; } Game.MessageQueue.AddMessage("Open Ground Attack!"); int noCardinals = FindNumberOfCardinals(target); if (noCardinals > 1) { bonus += noCardinals; Game.MessageQueue.AddMessage("Close Quarters!"); } //Bonus to hit and damage CombatResults results = Game.Dungeon.Player.AttackMonsterWithModifiers(target as Monster, bonus, 0, bonus, 0, true); Screen.Instance.DrawMeleeAttack(Game.Dungeon.Player, target, results); //Move into destination square (already check this was OK) if (!noMove) { Game.Dungeon.MovePCAbsoluteSameLevel(locationAfterMove.x, locationAfterMove.y); } //Stop any complaints about the ID not being valid if (!target.Alive) { currentTargetID = -1; } //ResetStatus(); LogFile.Log.LogEntryDebug("OpenSpaceAttack attack: " + bonus, LogDebugLevel.Low); //Fifth move is end and requires another attack to restart //Don't like this //if (moveCounter == 5) //{ // LogFile.Log.LogEntry("OpenSpaceAttack finished "); // ResetStatus(); //} }
public override void OnDefend(CombatResults results) { if (results.DidCrit) { CombatManager.PerformAbility(results.Target, results.Caster, new Ability_CounterStrike()); CombatManager.PerformAbility(results.Target, results.Caster, new Ability_CounterStrike()); } base.OnDefend(results); }
public override void sendCombatLog(CombatResults result, Character target, int damage, int enemiesHit = 1) { string log = RT.rt_setColor(character.textColor) + character.name + RT.rt_endColor() + " hit " + enemiesHit + " enemies " + " for " + RT.rt_setColor(RTColors.red) + damage + RT.rt_endColor() + " damage"; if (enemiesHit == 0) { log = "Whirlwind Missed..."; } CombatLogger.instance.logEffectString(log); }
public override void sendCombatLog(CombatResults result, Character target, int damage, int enemiesHit = 1) { string log = ""; log += RT.rt_setColor(character.textColor) + character.name + RT.rt_endColor() + " applied Burn to " + enemiesHit; log += enemiesHit > 1 ? " enemies" : " enemy"; if (enemiesHit == 0) { log = abilityName + " Misses..."; } CombatLogger.instance.logEffectString(log); }
public override void useAbilty(Character target) { int damage = getRoundedDamage(damagerPerIntellect, character.stats.intellect); CombatResults result = target.health.attemptDamage(damage, character.stats.intellect, target.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; target.health.takeDamage(damage); } sendCombatLog(result, target, damage); }
public override void useAbilty(Character target) { base.useAbilty(target); int roll = Mathf.RoundToInt((character.stats.intellect + character.stats.strength) / 2.0f); CombatResults result = target.health.attemptDamage(0, roll, character.stats.critBonusRoll); if (!result.miss) { target.health.applyEffect(new Stun(stunDuration)); } sendCombatLog(result, target, stunDuration); }
public override void DoMove(Point deltaMove, bool noMove) { Point locationAfterMove = Game.Dungeon.Player.LocationMap + deltaMove; //Bonus to hit and damage Game.MessageQueue.AddMessage("Charge attack!"); int bonus = moveCounter; if (moveCounter > 5) { bonus = 5; } //Add a bonus for close quarters if applicable int noCardinals = FindNumberOfCardinals(target); if (noCardinals > 1) { bonus += noCardinals; Game.MessageQueue.AddMessage("Close Quarters!"); } CombatResults results = Game.Dungeon.Player.AttackMonsterWithModifiers(target, bonus, 0, bonus, 0, true); Screen.Instance.DrawMeleeAttack(Game.Dungeon.Player, target, results); moveCounter = 0; moveReady = false; //Standard move into square, copied from PCMove bool okToMoveIntoSquare = false; if (results == CombatResults.DefenderDied) { okToMoveIntoSquare = true; } if (okToMoveIntoSquare) { Game.Dungeon.MovePCAbsoluteSameLevel(locationAfterMove.x, locationAfterMove.y); } //Give the player a small speed up //Seems to mean you get a free attack about 1 time in 2 //Game.Dungeon.Player.AddEffect(new PlayerEffects.SpeedUp(Game.Dungeon.Player, 50, 100)); LogFile.Log.LogEntryDebug("Charge complete", LogDebugLevel.Medium); //Game.MessageQueue.AddMessage("Wall Vault!"); }
public override void useAbilty(Character target) { int bleedDamage = getRoundedDamage(bleedDamagePerStrength, character.stats.strength); int damage = getRoundedDamage(damagePerStrength, character.stats.strength); CombatResults result = target.health.attemptDamage(damage, character.stats.strength, character.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; target.health.takeDamage(damage); target.health.applyEffect(new Bleed(bleedDuration, bleedDamage)); } sendCombatLog(result, target, damage); }
public override void useAbilty(Character target) { base.useAbilty(target); int roll = Mathf.RoundToInt((character.stats.intellect + character.stats.strength) / 2.0f); int damage = getRoundedDamage(damagerPerCombined, roll); CombatResults result = target.health.attemptDamage(damage, character.stats.strength, target.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; target.health.takeDamage(damage); } sendCombatLog(result, target, damage); }
public override void useAbilty(Character target) { base.useAbilty(target); int damage = getRoundedDamage(damagerPerAgility, character.stats.agility); CombatResults result = target.health.attemptDamage(damage, character.stats.agility, character.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; target.health.takeDamage(damage); target.health.applyEffect(new Stun(stunDuration)); } sendCombatLog(result, target, damage); }
public override void OnAttack(CombatResults results) { if (results.DidMiss || results.DidAvoid) { addCritBonus(5); } else if (results.DidCrit) { bonusCrit = 0.0; bonusHit = 0.0; } base.OnAttack(results); }
public override void sendCombatLog(CombatResults result, Character target, int damage, int enemiesHit = 1) { string log1 = RT.rt_setColor(character.textColor) + character.name + RT.rt_endColor() + " uses " + abilityName + ". "; string log2 = ""; if (result.miss) { log2 += "It Misses..."; } else { log2 += RT.rt_setColor(target.textColor) + target.name + RT.rt_endColor() + " takes " + RT.rt_setColor(RTColors.red) + damage + RT.rt_endColor() + " damage. Party Agility is boosted by " + agiltyBoost + " for " + enemiesHit + " turns"; } CombatLogger.instance.logCombatString(log1, log2); }
public override void sendCombatLog(CombatResults result, Character target, int damage, int enemiesHit = 1) { string log1 = character.name + " uses " + abilityName + " on " + RT.rt_setColor(target.textColor) + target.name + RT.rt_endColor() + "."; string log2 = ""; if (result.miss) { log2 += "It Misses..."; } else { log2 += target.name + " is stunned for " + damage + " turns"; } CombatLogger.instance.logCombatString(log1, log2); }
public override void useAbilty(Character target) { int damage = getRoundedDamage(damagePerEnemyConstition, target.stats.strength); int heal = Mathf.RoundToInt(healthPercent * character.health.maxHealth); CombatResults result = target.health.attemptDamage(damage, target.stats.strength, character.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; heal = result.crit ? heal * 2 : heal; target.health.takeDamage(damage); character.health.heal(heal); } sendCombatLog(result, target, damage, heal); }
public override void useAbilty(Character target) { int drainSP = getRoundedDamage(drainPerWisdom, character.stats.wisdom); int damage = getRoundedDamage(damagePerIntellect, character.stats.intellect); CombatResults result = target.health.attemptDamage(damage, character.stats.intellect, character.stats.critBonusRoll); if (!result.miss) { damage = result.crit ? damage * 2 : damage; drainSP = result.crit ? drainSP * 2 : drainSP; target.health.takeDamage(damage); target.health.changeCurrentSP(drainSP); } sendCombatLog(result, target, damage, drainSP); }
public override void useAbilty(Character target) { base.useAbilty(target); int enemiesHit = 0; for (int i = 0; i < TurnManager.instance.enemiesInCombat.Count; i++) { CombatResults result = TurnManager.instance.enemiesInCombat[i].health.attemptDamage(0, character.stats.strength, character.stats.critBonusRoll); if (!result.miss) { TurnManager.instance.enemiesInCombat[i].health.applyEffect(new StatDown(Stat.Str, decreaseAmount, duration)); enemiesHit++; } } sendCombatLog(null, null, decreaseAmount, enemiesHit); }
/// <summary> /// Do a melee attack animation /// </summary> /// <param name="monsterFightAndRunAI"></param> /// <param name="newTarget"></param> internal void DrawMeleeAttack(Creature creature, Creature newTarget, CombatResults result) { if (!CombatAnimations) return; //Check that the player can see the action MapSquare creatureSquare = Game.Dungeon.Levels[creature.LocationLevel].mapSquares[creature.LocationMap.x, creature.LocationMap.y]; MapSquare targetSquare = Game.Dungeon.Levels[newTarget.LocationLevel].mapSquares[newTarget.LocationMap.x, newTarget.LocationMap.y]; if (!creatureSquare.InPlayerFOV && !targetSquare.InPlayerFOV) return; //Draw screen normally //Necessary since on a player move, his old position will show unless we do this Draw(); FlushConsole(); //Flash the attacker /* Color creatureColor = creature.RepresentationColor(); if (creatureSquare.InPlayerFOV) { rootConsole.ForegroundColor = ColorPresets.White; rootConsole.PutChar(mapTopLeft.x + creature.LocationMap.x, mapTopLeft.y + creature.LocationMap.y, creature.Representation); } */ //Flash the attacked creature //Add flash to animation layer if (targetSquare.InPlayerFOV) { if (result == CombatResults.DefenderDamaged || result == CombatResults.DefenderDied) { if (isViewVisible(newTarget.LocationMap)) { tileMapLayer(TileLevel.Animations)[ViewRelative(newTarget.LocationMap)] = new TileEngine.TileCell(newTarget.Representation); tileMapLayer(TileLevel.Animations)[ViewRelative(newTarget.LocationMap)].TileFlag = new LibtcodColorFlags(ColorPresets.Red); } } } //Render the full layered map (with these animations) on screen MapRendererLibTCod.RenderMap(tileMap, new Point(0, 0), new System.Drawing.Rectangle(mapTopLeft.x, mapTopLeft.y, mapBotRightBase.x - mapTopLeftBase.x + 1, mapBotRightBase.y - mapTopLeftBase.y + 1)); FlushConsole(); //Wait TCODSystem.Sleep(meleeDelay); //Wipe the animation layer tileMap.ClearLayer((int)TileLevel.Animations); //Draw the map normally MapRendererLibTCod.RenderMap(tileMap, new Point(0, 0), new System.Drawing.Rectangle(mapTopLeft.x, mapTopLeft.y, mapBotRightBase.x - mapTopLeftBase.x + 1, mapBotRightBase.y - mapTopLeftBase.y + 1)); FlushConsole(); }
/// <summary> /// Do a missile attack animation. creature firing from start to finish in color. /// Currently checks if the target and origin creature are in FOV but not the path itself /// Currently only used for MvP attacks /// </summary> /// <param name="LocationMap"></param> /// <param name="point"></param> /// <param name="point_3"></param> /// <param name="color"></param> internal void DrawMissileAttack(Creature originCreature, Creature target, CombatResults result, Color color) { if (!CombatAnimations) return; //Check that the player can see the action MapSquare creatureSquare = Game.Dungeon.Levels[originCreature.LocationLevel].mapSquares[originCreature.LocationMap.x, originCreature.LocationMap.y]; MapSquare targetSquare = Game.Dungeon.Levels[target.LocationLevel].mapSquares[target.LocationMap.x, target.LocationMap.y]; if (!creatureSquare.InPlayerFOV && !targetSquare.InPlayerFOV) return; //Draw the screen as normal Draw(); FlushConsole(); //Flash the attacker /* if (creatureSquare.InPlayerFOV) { rootConsole.ForegroundColor = ColorPresets.White; rootConsole.PutChar(mapTopLeft.x + originCreature.LocationMap.x, mapTopLeft.y + originCreature.LocationMap.y, originCreature.Representation); }*/ //Draw animation to animation layer //Calculate and draw the line overlay DrawPathLine(TileLevel.Animations, originCreature.LocationMap, target.LocationMap, color, ColorPresets.Black); //Flash the target if they were damaged //Draw them in either case so that we overwrite the missile animation on the target square with the creature if (targetSquare.InPlayerFOV) { Color colorToDraw = ColorPresets.Red; if (result == CombatResults.DefenderDamaged || result == CombatResults.DefenderDied) { } else { colorToDraw = target.RepresentationColor(); } if (isViewVisible(target.LocationMap)) { tileMapLayer(TileLevel.Animations)[ViewRelative(target.LocationMap)] = new TileEngine.TileCell(target.Representation); tileMapLayer(TileLevel.Animations)[ViewRelative(target.LocationMap)].TileFlag = new LibtcodColorFlags(colorToDraw); } } //Render the full layered map (with these animations) on screen MapRendererLibTCod.RenderMap(tileMap, new Point(0, 0), new System.Drawing.Rectangle(mapTopLeft.x, mapTopLeft.y, mapBotRightBase.x - mapTopLeftBase.x + 1, mapBotRightBase.y - mapTopLeftBase.y + 1)); FlushConsole(); //Wait TCODSystem.Sleep(missileDelay); //Wipe the animation layer tileMap.ClearLayer((int)TileLevel.Animations); //Draw the map normally MapRendererLibTCod.RenderMap(tileMap, new Point(0, 0), new System.Drawing.Rectangle(mapTopLeft.x, mapTopLeft.y, mapBotRightBase.x - mapTopLeftBase.x + 1, mapBotRightBase.y - mapTopLeftBase.y + 1)); FlushConsole(); }