v0.9.2: finished reworking combo

This commit is contained in:
Evan Debenham 2021-02-13 14:34:50 -05:00
parent 70e080ca6f
commit c1dd816a36
4 changed files with 218 additions and 161 deletions

View File

@ -122,12 +122,12 @@ actors.buffs.combo.name=Combo
actors.buffs.combo.combo=%d hit combo! actors.buffs.combo.combo=%d hit combo!
actors.buffs.combo.bad_target=You must target an enemy in attack range. actors.buffs.combo.bad_target=You must target an enemy in attack range.
actors.buffs.combo.prompt=Select a target to attack. actors.buffs.combo.prompt=Select a target to attack.
actors.buffs.combo.desc=The gladiator builds momentum as they land successful blows. Each attack increases the combo counter by one, but taking too long between hits will reset the combo counter to 0.\n\nBuilding combo unlocks special combo attacks that cannot miss! A different attack is unlocked at 2, 4, 6, 8, and 10 combo count. actors.buffs.combo.desc=The gladiator builds momentum as they land successful blows. Each attack increases the combo counter by one, but taking too long between hits will reset the combo counter to 0.\n\nBuilding combo unlocks special combo attacks that cannot miss! A different attack is unlocked at 2, 4, 6, 8, and 10 combo count. Some moves reset combo and some do not, but each move can only be used once per combo session.
actors.buffs.combo$combomove.clobber_desc=_Clobber_ knocks an enemy back 2 tiles, but deals no damage and cannot knock into pits. Requires 2 combo, increments combo by 1, 1 use per combo. actors.buffs.combo$combomove.clobber_desc=_2 Combo: Clobber_ knocks an enemy back 2 tiles, but deals no damage and cannot knock into pits. Increments combo by 1.
actors.buffs.combo$combomove.slam_desc=_Slam_ deals 20% of your armor's blocking power as bonus damage for each combo you have. Requires 4 combo, resets combo when used. actors.buffs.combo$combomove.slam_desc=_4 Combo: Slam_ deals combo*20% of your armor's blocking power as bonus damage. Resets combo when used.
actors.buffs.combo$combomove.parry_desc=_Parry_ ... . Requires 6 combo, resets combo if nothing is parried, 1 use per combo. actors.buffs.combo$combomove.parry_desc=_6 Combo: Parry_ blocks the next attack within 1 turn when activated, and instantly retaliates to it. Resets combo if nothing is parried.
actors.buffs.combo$combomove.crush_desc=_???_ ... . Requires 8 combo, resets combo when used. actors.buffs.combo$combomove.crush_desc=_8 Combo: Crush_ deals combo*25% of your melee damage to the primary target, and half that damage to all other enemies in a 7x7 AOE. Resets combo when used.
actors.buffs.combo$combomove.fury_desc=_???_ ... . Requires 10 combo, resets combo when used. actors.buffs.combo$combomove.fury_desc=_10 Combo: Fury_ hits an enemy once for each combo you have, each hit deals 60% damage and can trigger enchantments. Resets combo when used.
actors.buffs.corruption.name=Corrupted actors.buffs.corruption.name=Corrupted
actors.buffs.corruption.desc=Corruption seeps into the essence of a being, twisting them against their former nature.\n\nCorrupted creatures will attack their allies, and ignore their former enemies. Corruption is damaging as well, and will slowly cause its target to succumb.\n\nCorruption is permanent, its effects only end in death. actors.buffs.corruption.desc=Corruption seeps into the essence of a being, twisting them against their former nature.\n\nCorrupted creatures will attack their allies, and ignore their former enemies. Corruption is damaging as well, and will slowly cause its target to succumb.\n\nCorruption is permanent, its effects only end in death.

View File

@ -47,6 +47,7 @@ import com.watabou.noosa.Image;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class Combo extends Buff implements ActionIndicator.Action { public class Combo extends Buff implements ActionIndicator.Action {
@ -167,15 +168,14 @@ public class Combo extends Buff implements ActionIndicator.Action {
@Override @Override
public void doAction() { public void doAction() {
GameScene.show(new WndCombo(this)); GameScene.show(new WndCombo(this));
//GameScene.selectCell(finisher);
} }
public enum ComboMove { public enum ComboMove {
CLOBBER(2, 0xFF00FF00), CLOBBER(2, 0xFF00FF00),
SLAM (4, 0xFFCCFF00), SLAM (4, 0xFFCCFF00),
PARRY (6, 0xFFFFFF00), //TODO implement PARRY (6, 0xFFFFFF00),
CRUSH (8, 0xFFFFCC00), //TODO rework CRUSH (8, 0xFFFFCC00),
FURY (10, 0xFFFF0000); //TODO rework FURY (10, 0xFFFF0000); //TODO can currently input other actions while attacking with fury
public int comboReq, tintColor; public int comboReq, tintColor;
@ -211,42 +211,54 @@ public class Combo extends Buff implements ActionIndicator.Action {
public void useMove(ComboMove move){ public void useMove(ComboMove move){
if (move == ComboMove.PARRY){ if (move == ComboMove.PARRY){
//TODO
parryUsed = true; parryUsed = true;
Buff.affect(target, ParryTracker.class, Actor.TICK);
((Hero)target).spendAndNext(Actor.TICK);
} else { } else {
moveBeingUsed = move; moveBeingUsed = move;
GameScene.selectCell(listener); GameScene.selectCell(listener);
} }
} }
private static ComboMove moveBeingUsed; public static class ParryTracker extends FlavourBuff{
{ actPriority = HERO_PRIO+1;}
private CellSelector.Listener listener = new CellSelector.Listener() { public boolean parried;
@Override @Override
public void onSelect(Integer cell) { public void detach() {
if (cell == null) return; if (!parried) target.buff(Combo.class).detach();
final Char enemy = Actor.findChar( cell ); super.detach();
if (enemy == null }
|| !Dungeon.level.heroFOV[cell] }
|| !((Hero)target).canAttack(enemy)
|| target.isCharmedBy( enemy )){ public static class RiposteTracker extends Buff{
GLog.w( Messages.get(Combo.class, "bad_target") ); { actPriority = VFX_PRIO;}
} else {
target.sprite.attack(cell, new Callback() { public Char enemy;
@Override
public boolean act() {
moveBeingUsed = ComboMove.PARRY;
target.sprite.attack(enemy.pos, new Callback() {
@Override @Override
public void call() { public void call() {
doAttack(enemy); target.buff(Combo.class).doAttack(enemy);
} }
}); });
detach();
return true;
} }
} }
private static ComboMove moveBeingUsed;
private void doAttack(final Char enemy){ private void doAttack(final Char enemy){
AttackIndicator.target(enemy); AttackIndicator.target(enemy);
boolean wasAlly = enemy.alignment == target.alignment; boolean wasAlly = enemy.alignment == target.alignment;
Hero hero = (Hero)target;
if (enemy.defenseSkill(target) >= Char.INFINITE_EVASION){ if (enemy.defenseSkill(target) >= Char.INFINITE_EVASION){
enemy.sprite.showStatus( CharSprite.NEUTRAL, enemy.defenseVerb() ); enemy.sprite.showStatus( CharSprite.NEUTRAL, enemy.defenseVerb() );
@ -269,12 +281,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
dmg += Math.round(target.drRoll() * count/5f); dmg += Math.round(target.drRoll() * count/5f);
break; break;
case CRUSH: case CRUSH:
//rolls 4 times, takes the highest roll dmg = Math.round(dmg * 0.25f*count);
for (int i = 1; i < 4; i++) {
int dmgReroll = target.damageRoll();
if (dmgReroll > dmg) dmg = dmgReroll;
}
dmg = Math.round(dmg * 2.5f);
break; break;
case FURY: case FURY:
dmg = Math.round(dmg * 0.6f); dmg = Math.round(dmg * 0.6f);
@ -294,6 +301,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
//special effects //special effects
switch (moveBeingUsed) { switch (moveBeingUsed) {
case CLOBBER: case CLOBBER:
hit( enemy );
if (enemy.isAlive()) { if (enemy.isAlive()) {
//trace a ballistica to our target (which will also extend past them //trace a ballistica to our target (which will also extend past them
Ballistica trajectory = new Ballistica(target.pos, enemy.pos, Ballistica.STOP_TARGET); Ballistica trajectory = new Ballistica(target.pos, enemy.pos, Ballistica.STOP_TARGET);
@ -305,13 +313,32 @@ public class Combo extends Buff implements ActionIndicator.Action {
dist--; dist--;
} }
WandOfBlastWave.throwChar(enemy, trajectory, dist, true, false); WandOfBlastWave.throwChar(enemy, trajectory, dist, true, false);
hit( enemy );
} }
break; break;
case SLAM: case PARRY:
BrokenSeal.WarriorShield shield = Buff.affect(target, BrokenSeal.WarriorShield.class); hit( enemy );
if (shield != null) { break;
shield.supercharge(dmg / 2); case CRUSH:
WandOfBlastWave.BlastWave.blast(enemy.pos);
PathFinder.buildDistanceMap(target.pos, Dungeon.level.passable, 3);
for (Char ch : Actor.chars()){
if (ch != enemy && ch.alignment == Char.Alignment.ENEMY
&& PathFinder.distance[ch.pos] < Integer.MAX_VALUE){
int aoeHit = Math.round(target.damageRoll() * 0.25f*count);
aoeHit /= 2;
aoeHit -= ch.drRoll();
if (ch.buff(Vulnerable.class) != null) aoeHit *= 1.33f;
ch.damage(aoeHit, target);
ch.sprite.bloodBurstA(target.sprite.center(), dmg);
ch.sprite.flash();
if (!ch.isAlive()) {
if (hero.hasTalent(Talent.LETHAL_DEFENSE) && hero.buff(BrokenSeal.WarriorShield.class) != null){
BrokenSeal.WarriorShield shield = hero.buff(BrokenSeal.WarriorShield.class);
shield.supercharge(Math.round(shield.maxShield() * hero.pointsInTalent(Talent.LETHAL_DEFENSE)/3f));
}
}
}
} }
break; break;
default: default:
@ -333,8 +360,6 @@ public class Combo extends Buff implements ActionIndicator.Action {
} }
Hero hero = (Hero)target;
//Post-attack behaviour //Post-attack behaviour
switch(moveBeingUsed){ switch(moveBeingUsed){
case CLOBBER: case CLOBBER:
@ -343,18 +368,9 @@ public class Combo extends Buff implements ActionIndicator.Action {
hero.spendAndNext(hero.attackDelay()); hero.spendAndNext(hero.attackDelay());
break; break;
/*case CLEAVE: case PARRY:
//combo isn't reset, but rather increments with a cleave kill, and grants more time. hero.next();
//this includes corrupting kills (which is why we check alignment break;
if (!enemy.isAlive() || (!wasAlly && enemy.alignment == target.alignment)) {
hit( enemy );
comboTime = 12f;
} else {
detach();
ActionIndicator.clearAction(Combo.this);
}
hero.spendAndNext(hero.attackDelay());
break;*/
case FURY: case FURY:
count--; count--;
@ -390,6 +406,27 @@ public class Combo extends Buff implements ActionIndicator.Action {
} }
private CellSelector.Listener listener = new CellSelector.Listener() {
@Override
public void onSelect(Integer cell) {
if (cell == null) return;
final Char enemy = Actor.findChar( cell );
if (enemy == null
|| !Dungeon.level.heroFOV[cell]
|| !((Hero)target).canAttack(enemy)
|| target.isCharmedBy( enemy )){
GLog.w( Messages.get(Combo.class, "bad_target") );
} else {
target.sprite.attack(cell, new Callback() {
@Override
public void call() {
doAttack(enemy);
}
});
}
}
@Override @Override
public String prompt() { public String prompt() {
return Messages.get(Combo.class, "prompt"); return Messages.get(Combo.class, "prompt");

View File

@ -52,6 +52,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Monk;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell; import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
@ -410,6 +411,13 @@ public class Hero extends Char {
@Override @Override
public int defenseSkill( Char enemy ) { public int defenseSkill( Char enemy ) {
if (buff(Combo.ParryTracker.class) != null){
if (canAttack(enemy)){
Buff.affect(this, Combo.RiposteTracker.class).enemy = enemy;
}
return INFINITE_EVASION;
}
float evasion = defenseSkill; float evasion = defenseSkill;
evasion *= RingOfEvasion.evasionMultiplier( this ); evasion *= RingOfEvasion.evasionMultiplier( this );
@ -425,6 +433,18 @@ public class Hero extends Char {
return Math.round(evasion); return Math.round(evasion);
} }
@Override
public String defenseVerb() {
Combo.ParryTracker parry = buff(Combo.ParryTracker.class);
if (parry == null){
return super.defenseVerb();
} else {
parry.parried = true;
parry.detach();
return Messages.get(Monk.class, "parried");
}
}
@Override @Override
public int drRoll() { public int drRoll() {
int dr = 0; int dr = 0;

View File

@ -36,7 +36,7 @@ import com.watabou.noosa.Image;
public class WndCombo extends Window { public class WndCombo extends Window {
private static final int WIDTH_P = 120; private static final int WIDTH_P = 120;
private static final int WIDTH_L = 144; private static final int WIDTH_L = 160;
private static final int MARGIN = 2; private static final int MARGIN = 2;