v0.9.2: implemented a new window where combo moves can be selected

This commit is contained in:
Evan Debenham 2021-02-03 18:55:23 -05:00
parent 4e95d6e238
commit a8967b6ece
5 changed files with 160 additions and 55 deletions

View File

@ -121,17 +121,13 @@ actors.buffs.chill.desc=Not quite frozen, but still much too cold.\n\nChilled ta
actors.buffs.combo.name=Combo 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.clobber_prompt=Select a target to Clobber\nDazes and knocks back actors.buffs.combo.prompt=Select a target to attack.
actors.buffs.combo.clobber_desc=_Clobber_ is currently available. This attack _knocks an enemy back and dazes them,_ but deals reduced damage. It's excellent for buying a little time during a fight. 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.cleave_prompt=Select a target to Cleave\nIf it kills, preserves combo actors.buffs.combo$combomove.clobber_desc=_Clobber_ knocks an enemy back 2 tiles, but not into a pit. Requires 2 combo, increments combo by 1, 1 use per combo.
actors.buffs.combo.cleave_desc=_Cleave_ is currently available. This attack deals increased damage, and _if it kills an enemy, it will preserve combo instead of resetting it._ It's great for building combo when fighting multiple enemies. actors.buffs.combo$combomove.cleave_desc=_Clobber_ knocks an enemy back 2 tiles, but not into a pit. Requires 2 combo, increments combo by 1, 1 use per combo.
actors.buffs.combo.slam_prompt=Select a target to Slam\nShields and damages based on armor actors.buffs.combo$combomove.slam_desc=_Clobber_ knocks an enemy back 2 tiles, but not into a pit. Requires 2 combo, increments combo by 1, 1 use per combo.
actors.buffs.combo.slam_desc=_Slam_ is currently available. This attack deals _increased damage and shields you based on the blocking power of your armor._ It's great for finishing a fight, letting you carry over endurance to the next one. actors.buffs.combo$combomove.crush_desc=_Clobber_ knocks an enemy back 2 tiles, but not into a pit. Requires 2 combo, increments combo by 1, 1 use per combo.
actors.buffs.combo.crush_prompt=Select a target to Crush\nDeals lots of damage actors.buffs.combo$combomove.fury_desc=_Clobber_ knocks an enemy back 2 tiles, but not into a pit. Requires 2 combo, increments combo by 1, 1 use per combo.
actors.buffs.combo.crush_desc=_Crush_ is currently available. This devastating attack _deals massive damage very consistently._ It's great for taking down a powerful opponent from high health!
actors.buffs.combo.fury_prompt=Unload fury on which enemy?\nAttacks many times rapidly
actors.buffs.combo.fury_desc=_Fury_ is currently available. This devastating attack _hits as many times as your current combo count,_ albeit at reduced damage. Fury is great if you have a weapon enchant, as the enchant will activate on each hit!
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 finisher abilities: powerful attacks that cannot miss! A different finisher is available at 2, 4, 6, 8, and 10 combo count, and using a finisher will reset your combo.
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

@ -9,6 +9,8 @@ windows.wndchooseway.cancel=I'll decide later
windows.wndclass.mastery=Mastery windows.wndclass.mastery=Mastery
windows.wndcombo.title=choose a combo move
windows.wnddocument.missing=page missing windows.wnddocument.missing=page missing
windows.wnderror.title=ERROR windows.wnderror.title=ERROR

View File

@ -42,6 +42,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndCombo;
import com.watabou.noosa.Image; 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;
@ -60,12 +61,12 @@ public class Combo extends Buff implements ActionIndicator.Action {
@Override @Override
public void tintIcon(Image icon) { public void tintIcon(Image icon) {
if (count >= 10) icon.hardlight(1f, 0f, 0f); ComboMove move = getHighestMove();
else if (count >= 8)icon.hardlight(1f, 0.8f, 0f); if (move != null){
else if (count >= 6)icon.hardlight(1f, 1f, 0f); icon.hardlight(move.tintColor & 0x00FFFFFF);
else if (count >= 4)icon.hardlight(0.8f, 1f, 0f); } else {
else if (count >= 2)icon.hardlight(0f, 1f, 0f); icon.resetColor();
else icon.resetColor(); }
} }
@Override @Override
@ -83,11 +84,12 @@ public class Combo extends Buff implements ActionIndicator.Action {
count++; count++;
comboTime = 5f; comboTime = 5f;
//TODO this won't count a kill on an enemy that gets corruped by corrupting I think?
if (!enemy.isAlive() || enemy.buff(Corruption.class) != null){ if (!enemy.isAlive() || enemy.buff(Corruption.class) != null){
comboTime = Math.max(comboTime, 10*((Hero)target).pointsInTalent(Talent.CLEAVE)); comboTime = Math.max(comboTime, 10*((Hero)target).pointsInTalent(Talent.CLEAVE));
} }
if (count >= 2) { if ((getHighestMove() != null)) {
ActionIndicator.setAction( this ); ActionIndicator.setAction( this );
Badges.validateMasteryCombo( count ); Badges.validateMasteryCombo( count );
@ -118,15 +120,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
@Override @Override
public String desc() { public String desc() {
String desc = Messages.get(this, "desc"); return Messages.get(this, "desc");
if (count >= 10) desc += "\n\n" + Messages.get(this, "fury_desc");
else if (count >= 8)desc += "\n\n" + Messages.get(this, "crush_desc");
else if (count >= 6)desc += "\n\n" + Messages.get(this, "slam_desc");
else if (count >= 4)desc += "\n\n" + Messages.get(this, "cleave_desc");
else if (count >= 2)desc += "\n\n" + Messages.get(this, "clobber_desc");
return desc;
} }
private static final String COUNT = "count"; private static final String COUNT = "count";
@ -142,7 +136,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
public void restoreFromBundle(Bundle bundle) { public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle); super.restoreFromBundle(bundle);
count = bundle.getInt( COUNT ); count = bundle.getInt( COUNT );
if (count >= 2) ActionIndicator.setAction(this); if (getHighestMove() != null) ActionIndicator.setAction(this);
comboTime = bundle.getFloat( TIME ); comboTime = bundle.getFloat( TIME );
} }
@ -155,28 +149,60 @@ public class Combo extends Buff implements ActionIndicator.Action {
icon = new ItemSprite(new Item(){ {image = ItemSpriteSheet.WEAPON_HOLDER; }}); icon = new ItemSprite(new Item(){ {image = ItemSpriteSheet.WEAPON_HOLDER; }});
} }
if (count >= 10) icon.tint(0xFFFF0000); icon.tint(getHighestMove().tintColor);
else if (count >= 8)icon.tint(0xFFFFCC00);
else if (count >= 6)icon.tint(0xFFFFFF00);
else if (count >= 4)icon.tint(0xFFCCFF00);
else icon.tint(0xFF00FF00);
return icon; return icon;
} }
@Override @Override
public void doAction() { public void doAction() {
GameScene.selectCell(finisher); GameScene.show(new WndCombo(this));
//GameScene.selectCell(finisher);
} }
private enum finisherType{ public enum ComboMove {
//TODO rework these, as well as finisher mechanics in general //TODO rework these moves
CLOBBER, CLEAVE, SLAM, CRUSH, FURY CLOBBER(2, 0xFF00FF00),
CLEAVE(4, 0xFFCCFF00),
SLAM(6, 0xFFFFFF00),
CRUSH(8, 0xFFFFCC00),
FURY(10, 0xFFFF0000);
public int comboReq, tintColor;
ComboMove(int comboReq, int tintColor){
this.comboReq = comboReq;
this.tintColor = tintColor;
}
public String desc(){
return Messages.get(this, name()+"_desc");
}
} }
private CellSelector.Listener finisher = new CellSelector.Listener() { public ComboMove getHighestMove(){
ComboMove best = null;
for (ComboMove move : ComboMove.values()){
if (count >= move.comboReq){
best = move;
}
}
return best;
}
private finisherType type; public boolean canUseMove(ComboMove move){
return move.comboReq <= count;
}
public void useMove(ComboMove move){
moveBeingUsed = move;
GameScene.selectCell(listener);
}
private static ComboMove moveBeingUsed;
private CellSelector.Listener listener = new CellSelector.Listener() {
@Override @Override
public void onSelect(Integer cell) { public void onSelect(Integer cell) {
@ -191,11 +217,6 @@ public class Combo extends Buff implements ActionIndicator.Action {
target.sprite.attack(cell, new Callback() { target.sprite.attack(cell, new Callback() {
@Override @Override
public void call() { public void call() {
if (count >= 10) type = finisherType.FURY;
else if (count >= 8)type = finisherType.CRUSH;
else if (count >= 6)type = finisherType.SLAM;
else if (count >= 4)type = finisherType.CLEAVE;
else type = finisherType.CLOBBER;
doAttack(enemy); doAttack(enemy);
} }
}); });
@ -221,7 +242,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
int dmg = target.damageRoll(); int dmg = target.damageRoll();
//variance in damage dealt //variance in damage dealt
switch (type) { switch (moveBeingUsed) {
case CLOBBER: case CLOBBER:
dmg = Math.round(dmg * 0.6f); dmg = Math.round(dmg * 0.6f);
break; break;
@ -255,7 +276,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
enemy.damage(dmg, target); enemy.damage(dmg, target);
//special effects //special effects
switch (type) { switch (moveBeingUsed) {
case CLOBBER: case CLOBBER:
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
@ -282,7 +303,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
if (target.buff(FrostImbue.class) != null) target.buff(FrostImbue.class).proc(enemy); if (target.buff(FrostImbue.class) != null) target.buff(FrostImbue.class).proc(enemy);
target.hitSound(Random.Float(0.87f, 1.15f)); target.hitSound(Random.Float(0.87f, 1.15f));
if (type != finisherType.FURY) Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG); if (moveBeingUsed != ComboMove.FURY) Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
enemy.sprite.bloodBurstA(target.sprite.center(), dmg); enemy.sprite.bloodBurstA(target.sprite.center(), dmg);
enemy.sprite.flash(); enemy.sprite.flash();
@ -295,7 +316,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
Hero hero = (Hero)target; Hero hero = (Hero)target;
//Post-attack behaviour //Post-attack behaviour
switch(type){ switch(moveBeingUsed){
case CLEAVE: case CLEAVE:
//combo isn't reset, but rather increments with a cleave kill, and grants more time. //combo isn't reset, but rather increments with a cleave kill, and grants more time.
//this includes corrupting kills (which is why we check alignment //this includes corrupting kills (which is why we check alignment
@ -338,11 +359,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
@Override @Override
public String prompt() { public String prompt() {
if (count >= 10) return Messages.get(Combo.class, "fury_prompt"); return Messages.get(Combo.class, "prompt");
else if (count >= 8)return Messages.get(Combo.class, "crush_prompt");
else if (count >= 6)return Messages.get(Combo.class, "slam_prompt");
else if (count >= 4)return Messages.get(Combo.class, "cleave_prompt");
else return Messages.get(Combo.class, "clobber_prompt");
} }
}; };
} }

View File

@ -65,6 +65,7 @@ public class StyledButton extends Button {
if (icon != null) componentWidth += icon.width() + 2; if (icon != null) componentWidth += icon.width() + 2;
if (text != null && !text.text().equals("")){ if (text != null && !text.text().equals("")){
text.maxWidth( (int)(width - componentWidth - 2) );
componentWidth += text.width() + 2; componentWidth += text.width() + 2;
text.setPos( text.setPos(

View File

@ -0,0 +1,89 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.noosa.Image;
public class WndCombo extends Window {
private static final int WIDTH_P = 120;
private static final int WIDTH_L = 144;
private static final int MARGIN = 2;
public WndCombo( Combo combo ){
super();
int width = PixelScene.landscape() ? WIDTH_L : WIDTH_P;
float pos = MARGIN;
RenderedTextBlock title = PixelScene.renderTextBlock(Messages.titleCase(Messages.get(this, "title")), 9);
title.hardlight(TITLE_COLOR);
title.setPos((width-title.width())/2, pos);
title.maxWidth(width - MARGIN * 2);
add(title);
pos = title.bottom() + 3*MARGIN;
Image icon;
if (Dungeon.hero.belongings.weapon != null){
icon = new ItemSprite(Dungeon.hero.belongings.weapon.image, null);
} else {
icon = new ItemSprite(new Item(){ {image = ItemSpriteSheet.WEAPON_HOLDER; }});
}
for (Combo.ComboMove move : Combo.ComboMove.values()) {
Image ic = new Image(icon);
RedButton moveBtn = new RedButton(move.desc(), 6){
@Override
protected void onClick() {
super.onClick();
hide();
combo.useMove(move);
}
};
ic.tint(move.tintColor);
moveBtn.icon(ic);
moveBtn.setSize(width, moveBtn.reqHeight());
moveBtn.setRect(0, pos, width, moveBtn.reqHeight());
moveBtn.enable(combo.canUseMove(move));
add(moveBtn);
pos = moveBtn.bottom() + MARGIN;
}
resize(width, (int)pos);
}
}