v0.9.2: implemented a new window where combo moves can be selected
This commit is contained in:
parent
4e95d6e238
commit
a8967b6ece
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,9 @@ 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(
|
||||||
x + (width() + componentWidth)/2f - text.width() - 1,
|
x + (width() + componentWidth)/2f - text.width() - 1,
|
||||||
y + (height() - text.height()) / 2f
|
y + (height() - text.height()) / 2f
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user