v1.3.0: implemented new radial menus and made a bunch of keybind changes
This commit is contained in:
@@ -27,6 +27,8 @@ import com.badlogic.gdx.controllers.Controller;
|
||||
import com.badlogic.gdx.controllers.ControllerListener;
|
||||
import com.badlogic.gdx.controllers.ControllerMapping;
|
||||
import com.badlogic.gdx.controllers.Controllers;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.ui.Cursor;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
@@ -138,14 +140,32 @@ public class ControllerHandler implements ControllerListener {
|
||||
|
||||
//we use a separate variable as Gdx.input.isCursorCatched only works on desktop
|
||||
private static boolean controllerPointerActive = false;
|
||||
private static PointF controllerPointerPos;
|
||||
|
||||
public static void setControllerPointer( boolean active ){
|
||||
Gdx.input.setCursorCatched(active);
|
||||
if (controllerPointerActive == active) return;
|
||||
controllerPointerActive = active;
|
||||
if (active){
|
||||
Gdx.input.setCursorCatched(true);
|
||||
controllerPointerPos = new PointF(Game.width/2, Game.height/2);
|
||||
} else if (!Cursor.isCursorCaptured()) {
|
||||
Gdx.input.setCursorCatched(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean controllerPointerActive(){
|
||||
return controllerPointerActive;
|
||||
return controllerPointerActive && !Cursor.isCursorCaptured();
|
||||
}
|
||||
|
||||
public static PointF getControllerPointerPos(){
|
||||
return controllerPointerPos.clone();
|
||||
}
|
||||
|
||||
public static void updateControllerPointer(PointF pos, boolean sendEvent){
|
||||
controllerPointerPos.set(pos);
|
||||
if (sendEvent) {
|
||||
PointerEvent.addPointerEvent(new PointerEvent((int) controllerPointerPos.x, (int) controllerPointerPos.y, 10_000, PointerEvent.Type.HOVER, PointerEvent.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
//converts controller button codes to keyEvent codes
|
||||
@@ -199,6 +219,16 @@ public class ControllerHandler implements ControllerListener {
|
||||
} else if (keyCode == Input.Keys.BUTTON_Y){
|
||||
return "Triangle Button";
|
||||
}
|
||||
} else if (lastUsedType == ControllerType.XBOX){
|
||||
if (keyCode == Input.Keys.BUTTON_L1){
|
||||
return "Left Bumper";
|
||||
} else if (keyCode == Input.Keys.BUTTON_L2){
|
||||
return "Left Trigger";
|
||||
} else if (keyCode == Input.Keys.BUTTON_R1){
|
||||
return "Right Bumper";
|
||||
} else if (keyCode == Input.Keys.BUTTON_R2){
|
||||
return "Right Trigger";
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCode == Input.Keys.DPAD_UP + 1000){
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.badlogic.gdx.InputAdapter;
|
||||
import com.badlogic.gdx.InputMultiplexer;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.ui.Cursor;
|
||||
|
||||
public class InputHandler extends InputAdapter {
|
||||
|
||||
|
||||
@@ -82,19 +82,17 @@ public class KeyBindings {
|
||||
return GameAction.NONE;
|
||||
}
|
||||
|
||||
public static ArrayList<Integer> getBoundKeysForAction(GameAction action){
|
||||
ArrayList<Integer> result = new ArrayList<>();
|
||||
for( int i : bindings.keySet() ){
|
||||
if (bindings.get(i) == action){
|
||||
result.add(i);
|
||||
}
|
||||
public static int getFirstKeyForAction(GameAction action, boolean preferController){
|
||||
ArrayList<Integer> keys = getKeyboardKeysForAction(action);
|
||||
ArrayList<Integer> buttons = getControllerKeysForAction(action);
|
||||
if (preferController){
|
||||
if (!buttons.isEmpty()) return buttons.get(0);
|
||||
else if (!keys.isEmpty()) return keys.get(0);
|
||||
} else {
|
||||
if (!keys.isEmpty()) return keys.get(0);
|
||||
else if (!buttons.isEmpty()) return buttons.get(0);
|
||||
}
|
||||
for( int i : controllerBindings.keySet() ){
|
||||
if (controllerBindings.get(i) == action){
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static ArrayList<Integer> getKeyboardKeysForAction(GameAction action){
|
||||
|
||||
@@ -23,10 +23,13 @@ package com.watabou.input;
|
||||
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.ui.Cursor;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PointerEvent {
|
||||
@@ -57,6 +60,10 @@ public class PointerEvent {
|
||||
}
|
||||
|
||||
public PointerEvent( int x, int y, int id, Type type, int button){
|
||||
if (Cursor.isCursorCaptured()){
|
||||
x = Game.width/2;
|
||||
y = Game.width/2;
|
||||
}
|
||||
start = current = new PointF(x, y);
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
|
||||
@@ -24,7 +24,10 @@ package com.watabou.noosa.ui;
|
||||
import com.badlogic.gdx.Files;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.FileUtils;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class Cursor {
|
||||
|
||||
@@ -86,4 +89,30 @@ public class Cursor {
|
||||
|
||||
}
|
||||
|
||||
private static boolean cursorCaptured = false;
|
||||
|
||||
public static void captureCursor(boolean captured){
|
||||
cursorCaptured = captured;
|
||||
|
||||
if (captured) {
|
||||
Gdx.input.setCursorCatched(true);
|
||||
} else {
|
||||
if (ControllerHandler.controllerPointerActive()) {
|
||||
ControllerHandler.setControllerPointer(true);
|
||||
ControllerHandler.updateControllerPointer(new PointF(Game.width/2, Game.height/2), false);
|
||||
} else {
|
||||
Gdx.input.setCursorCatched(false);
|
||||
Gdx.input.setCursorPosition(Game.width/2, Game.height/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PointF getCursorDelta(){
|
||||
return new PointF(Gdx.input.getDeltaX(), Gdx.input.getDeltaY());
|
||||
}
|
||||
|
||||
public static boolean isCursorCaptured(){
|
||||
return cursorCaptured;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -138,7 +138,11 @@ public class PointF {
|
||||
float dy = a.y - b.y;
|
||||
return (float)Math.sqrt( dx * dx + dy * dy );
|
||||
}
|
||||
|
||||
|
||||
public static float angle( float x, float y ) {
|
||||
return (float)Math.atan2( y, x );
|
||||
}
|
||||
|
||||
public static float angle( PointF start, PointF end ) {
|
||||
return (float)Math.atan2( end.y - start.y, end.x - start.x );
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ allprojects {
|
||||
appName = 'Shattered Pixel Dungeon'
|
||||
appPackageName = 'com.shatteredpixel.shatteredpixeldungeon'
|
||||
|
||||
appVersionCode = 636
|
||||
appVersionName = '1.3.0-BETA-2'
|
||||
appVersionCode = 637
|
||||
appVersionName = '1.3.0-BETA-3'
|
||||
|
||||
appJavaCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
|
||||
BIN
core/src/main/assets/interfaces/radial_menu.png
Normal file
BIN
core/src/main/assets/interfaces/radial_menu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -5,6 +5,18 @@ ui.talentspane.unlock_tier2=Reach level 6 to unlock more talents.
|
||||
ui.talentspane.unlock_tier3=Reach level 12 and defeat the second boss to unlock more talents.
|
||||
ui.talentspane.unlock_tier4=Reach level 20 and defeat the fourth boss to unlock more talents.
|
||||
|
||||
ui.toolbar.quickslot_prompt=Select a Quickslot
|
||||
ui.toolbar.quickslot_select=Select Quickslot
|
||||
ui.toolbar.quickslot_assign=Assign Quickslot
|
||||
ui.toolbar.quickslot_cancel=Cancel
|
||||
ui.toolbar.container_prompt=Select a Container
|
||||
ui.toolbar.container_select=Select Container
|
||||
ui.toolbar.container_cancel=Cancel
|
||||
ui.toolbar.container_empty=That container is empty!
|
||||
ui.toolbar.item_prompt=Select an Item
|
||||
ui.toolbar.item_select=Select Item
|
||||
ui.toolbar.item_use=Quick-use Item
|
||||
ui.toolbar.item_cancel=Cancel
|
||||
ui.toolbar.examine_prompt=Press again to search\nPress a tile to examine
|
||||
|
||||
ui.updatenotification.title=Update
|
||||
|
||||
@@ -117,8 +117,8 @@ windows.wndkeybindings.journal=Journal
|
||||
windows.wndkeybindings.wait=Wait
|
||||
windows.wndkeybindings.examine=Examine
|
||||
windows.wndkeybindings.rest=Rest
|
||||
windows.wndkeybindings.inventory_selector=Inventory Selector
|
||||
windows.wndkeybindings.inventory=Inventory
|
||||
windows.wndkeybindings.inventory_selector=Inventory Selector
|
||||
windows.wndkeybindings.quickslot_selector=Quickslot Selector
|
||||
windows.wndkeybindings.quickslot_1=Quickslot 1
|
||||
windows.wndkeybindings.quickslot_2=Quickslot 2
|
||||
@@ -136,8 +136,8 @@ windows.wndkeybindings.tag_danger=Switch Enemy
|
||||
windows.wndkeybindings.tag_action=Special Action
|
||||
windows.wndkeybindings.tag_loot=Pickup Item
|
||||
windows.wndkeybindings.tag_resume=Resume Motion
|
||||
windows.wndkeybindings.zoom_in=Zoom In / Scroll Up
|
||||
windows.wndkeybindings.zoom_out=Zoom Out / Scroll Down
|
||||
windows.wndkeybindings.zoom_in=Zoom In / Scroll Down
|
||||
windows.wndkeybindings.zoom_out=Zoom Out / Scroll Up
|
||||
windows.wndkeybindings.n=Go North
|
||||
windows.wndkeybindings.e=Go East
|
||||
windows.wndkeybindings.s=Go South
|
||||
|
||||
@@ -87,13 +87,15 @@ public class Assets {
|
||||
public static final String LOADING_CITY = "interfaces/loading_city.png";
|
||||
public static final String LOADING_HALLS = "interfaces/loading_halls.png";
|
||||
|
||||
public static final String BUFFS_SMALL = "interfaces/buffs.png";
|
||||
public static final String BUFFS_LARGE = "interfaces/large_buffs.png";
|
||||
public static final String BUFFS_SMALL = "interfaces/buffs.png";
|
||||
public static final String BUFFS_LARGE = "interfaces/large_buffs.png";
|
||||
|
||||
public static final String TALENT_ICONS = "interfaces/talent_icons.png";
|
||||
public static final String TALENT_BUTTON = "interfaces/talent_button.png";
|
||||
public static final String TALENT_ICONS = "interfaces/talent_icons.png";
|
||||
public static final String TALENT_BUTTON = "interfaces/talent_button.png";
|
||||
|
||||
public static final String HERO_ICONS = "interfaces/hero_icons.png";
|
||||
public static final String HERO_ICONS = "interfaces/hero_icons.png";
|
||||
|
||||
public static final String RADIAL_MENU = "interfaces/radial_menu.png";
|
||||
}
|
||||
|
||||
//these points to resource bundles, not raw asset files
|
||||
|
||||
@@ -57,6 +57,8 @@ public class SPDAction extends GameAction {
|
||||
public static final GameAction WAIT_OR_PICKUP = new SPDAction("wait_or_pickup");
|
||||
|
||||
public static final GameAction INVENTORY = new SPDAction("inventory");
|
||||
public static final GameAction INVENTORY_SELECTOR = new SPDAction("inventory_selector");
|
||||
public static final GameAction QUICKSLOT_SELECTOR = new SPDAction("quickslot_selector");
|
||||
public static final GameAction QUICKSLOT_1 = new SPDAction("quickslot_1");
|
||||
public static final GameAction QUICKSLOT_2 = new SPDAction("quickslot_2");
|
||||
public static final GameAction QUICKSLOT_3 = new SPDAction("quickslot_3");
|
||||
@@ -158,23 +160,20 @@ public class SPDAction extends GameAction {
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_L2, SPDAction.RIGHT_CLICK );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_SELECT, SPDAction.MIDDLE_CLICK );
|
||||
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_UP+1000, SPDAction.N );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_LEFT+1000, SPDAction.W );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_DOWN+1000, SPDAction.S );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_RIGHT+1000, SPDAction.E );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_UP+1000, SPDAction.TAG_ACTION );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_LEFT+1000, SPDAction.TAG_DANGER );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_DOWN+1000, SPDAction.TAG_RESUME );
|
||||
defaultControllerBindings.put( Input.Keys.DPAD_RIGHT+1000, SPDAction.TAG_LOOT );
|
||||
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_THUMBL, SPDAction.WAIT_OR_PICKUP );
|
||||
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_R1, SPDAction.INVENTORY );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_R1, SPDAction.ZOOM_IN );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_L1, SPDAction.ZOOM_OUT );
|
||||
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_L1, SPDAction.EXAMINE );
|
||||
|
||||
//plan for new buttons: quickslots, quick inventory,
|
||||
//Probably want to repurpose dpad too: attack, loot(or combine this?), special action, resume
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_Y, SPDAction.QUICKSLOT_1 );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_B, SPDAction.QUICKSLOT_2 );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_X, SPDAction.QUICKSLOT_3 );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_A, SPDAction.QUICKSLOT_4 );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_A, SPDAction.TAG_ATTACK );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_B, SPDAction.EXAMINE );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_X, SPDAction.QUICKSLOT_SELECTOR );
|
||||
defaultControllerBindings.put( Input.Keys.BUTTON_Y, SPDAction.INVENTORY_SELECTOR );
|
||||
}
|
||||
|
||||
public static LinkedHashMap<Integer, GameAction> getControllerDefaults() {
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
@@ -46,6 +47,9 @@ public class Belongings implements Iterable<Item> {
|
||||
private Hero owner;
|
||||
|
||||
public static class Backpack extends Bag {
|
||||
{
|
||||
image = ItemSpriteSheet.BACKPACK;
|
||||
}
|
||||
public int capacity(){
|
||||
int cap = super.capacity();
|
||||
for (Item item : items){
|
||||
|
||||
@@ -108,6 +108,10 @@ public class CircleArc extends Visual {
|
||||
this.sweep = sweep;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public float getSweep(){
|
||||
return sweep;
|
||||
}
|
||||
|
||||
private void updateTriangles(){
|
||||
|
||||
|
||||
@@ -160,34 +160,34 @@ public class PixelScene extends Scene {
|
||||
|
||||
}
|
||||
|
||||
private static PointF virtualCursorPos;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
//20% deadzone
|
||||
if (Math.abs(ControllerHandler.rightStickPosition.x) >= 0.2f
|
||||
|| Math.abs(ControllerHandler.rightStickPosition.y) >= 0.2f) {
|
||||
if (!ControllerHandler.controllerPointerActive()) {
|
||||
ControllerHandler.setControllerPointer(true);
|
||||
virtualCursorPos = PointerEvent.currentHoverPos();
|
||||
if (!Cursor.isCursorCaptured()) {
|
||||
if (Math.abs(ControllerHandler.rightStickPosition.x) >= 0.2f
|
||||
|| Math.abs(ControllerHandler.rightStickPosition.y) >= 0.2f) {
|
||||
if (!ControllerHandler.controllerPointerActive()) {
|
||||
ControllerHandler.setControllerPointer(true);
|
||||
}
|
||||
|
||||
int sensitivity = SPDSettings.controllerPointerSensitivity() * 100;
|
||||
|
||||
//cursor moves 100xsens scaled pixels per second at full speed
|
||||
//35x at 50% movement, ~9x at 20% deadzone threshold
|
||||
float xMove = (float) Math.pow(Math.abs(ControllerHandler.rightStickPosition.x), 1.5);
|
||||
if (ControllerHandler.rightStickPosition.x < 0) xMove = -xMove;
|
||||
|
||||
float yMove = (float) Math.pow(Math.abs(ControllerHandler.rightStickPosition.y), 1.5);
|
||||
if (ControllerHandler.rightStickPosition.y < 0) yMove = -yMove;
|
||||
|
||||
PointF virtualCursorPos = ControllerHandler.getControllerPointerPos();
|
||||
virtualCursorPos.x += defaultZoom * sensitivity * Game.elapsed * xMove;
|
||||
virtualCursorPos.y += defaultZoom * sensitivity * Game.elapsed * yMove;
|
||||
virtualCursorPos.x = GameMath.gate(0, virtualCursorPos.x, Game.width);
|
||||
virtualCursorPos.y = GameMath.gate(0, virtualCursorPos.y, Game.height);
|
||||
ControllerHandler.updateControllerPointer(virtualCursorPos, true);
|
||||
}
|
||||
|
||||
int sensitivity = SPDSettings.controllerPointerSensitivity() * 100;
|
||||
|
||||
//cursor moves 100xsens scaled pixels per second at full speed
|
||||
//35x at 50% movement, ~9x at 20% deadzone threshold
|
||||
float xMove = (float)Math.pow(Math.abs(ControllerHandler.rightStickPosition.x), 1.5);
|
||||
if (ControllerHandler.rightStickPosition.x < 0) xMove = -xMove;
|
||||
|
||||
float yMove = (float)Math.pow(Math.abs(ControllerHandler.rightStickPosition.y), 1.5);
|
||||
if (ControllerHandler.rightStickPosition.y < 0) yMove = -yMove;
|
||||
|
||||
virtualCursorPos.x += defaultZoom * sensitivity * Game.elapsed * xMove;
|
||||
virtualCursorPos.y += defaultZoom * sensitivity * Game.elapsed * yMove;
|
||||
virtualCursorPos.x = GameMath.gate(0, virtualCursorPos.x, Game.width);
|
||||
virtualCursorPos.y = GameMath.gate(0, virtualCursorPos.y, Game.height);
|
||||
PointerEvent.addPointerEvent(new PointerEvent((int) virtualCursorPos.x, (int) virtualCursorPos.y, 10_000, PointerEvent.Type.HOVER, PointerEvent.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ public class PixelScene extends Scene {
|
||||
cursor = new Image(Cursor.Type.CONTROLLER.file);
|
||||
}
|
||||
|
||||
PointF virtualCursorPos = ControllerHandler.getControllerPointerPos();
|
||||
cursor.x = (virtualCursorPos.x / defaultZoom) - cursor.width()/2f;
|
||||
cursor.y = (virtualCursorPos.y / defaultZoom) - cursor.height()/2f;
|
||||
cursor.camera = uiCamera;
|
||||
|
||||
@@ -84,18 +84,8 @@ public class Button extends Component {
|
||||
String text = hoverText();
|
||||
if (text != null){
|
||||
if (keyAction() != null){
|
||||
ArrayList<Integer> bindings = KeyBindings.getBoundKeysForAction(keyAction());
|
||||
if (!bindings.isEmpty()){
|
||||
int key = bindings.get(0);
|
||||
//prefer controller buttons if we are using a controller
|
||||
if (ControllerHandler.controllerPointerActive()){
|
||||
for (int code : bindings){
|
||||
if (ControllerHandler.icControllerKey(code)){
|
||||
key = code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int key = KeyBindings.getFirstKeyForAction(keyAction(), ControllerHandler.controllerPointerActive());
|
||||
if (key != 0){
|
||||
text += " _(" + KeyBindings.getKeyName(key) + ")_";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class QuickSlotButton extends Button {
|
||||
private Image crossB;
|
||||
private Image crossM;
|
||||
|
||||
private static boolean targeting = false;
|
||||
public static int targetingSlot = -1;
|
||||
public static Char lastTarget = null;
|
||||
|
||||
public QuickSlotButton( int slotNum ) {
|
||||
@@ -83,7 +83,7 @@ public class QuickSlotButton extends Button {
|
||||
if (!Dungeon.hero.isAlive() || !Dungeon.hero.ready){
|
||||
return;
|
||||
}
|
||||
if (targeting) {
|
||||
if (targetingSlot == slotNum) {
|
||||
int cell = autoAim(lastTarget, select(slotNum));
|
||||
|
||||
if (cell != -1){
|
||||
@@ -160,7 +160,7 @@ public class QuickSlotButton extends Button {
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (targeting && lastTarget != null && lastTarget.sprite != null){
|
||||
if (targetingSlot != -1 && lastTarget != null && lastTarget.sprite != null){
|
||||
crossM.point(lastTarget.sprite.center(crossM));
|
||||
}
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public class QuickSlotButton extends Button {
|
||||
lastTarget.alignment != Char.Alignment.ALLY &&
|
||||
Dungeon.level.heroFOV[lastTarget.pos]) {
|
||||
|
||||
targeting = true;
|
||||
targetingSlot = slotNum;
|
||||
CharSprite sprite = lastTarget.sprite;
|
||||
|
||||
if (sprite.parent != null) {
|
||||
@@ -284,7 +284,7 @@ public class QuickSlotButton extends Button {
|
||||
} else {
|
||||
|
||||
lastTarget = null;
|
||||
targeting = false;
|
||||
targetingSlot = -1;
|
||||
|
||||
}
|
||||
|
||||
@@ -337,11 +337,11 @@ public class QuickSlotButton extends Button {
|
||||
}
|
||||
|
||||
public static void cancel() {
|
||||
if (targeting) {
|
||||
if (targetingSlot != -1) {
|
||||
for (QuickSlotButton btn : instance) {
|
||||
btn.crossB.visible = false;
|
||||
btn.crossM.remove();
|
||||
targeting = false;
|
||||
targetingSlot = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 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.ui;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CircleArc;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.noosa.ColorBlock;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.ui.Cursor;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class RadialMenu extends Window {
|
||||
|
||||
int slots;
|
||||
float targetAngle;
|
||||
PointF center;
|
||||
|
||||
CircleArc selectionArc;
|
||||
RenderedTextBlock titleTxt;
|
||||
RenderedTextBlock descTxt;
|
||||
|
||||
String[] texts;
|
||||
Image[] icons;
|
||||
int selectedIdx = -1;
|
||||
|
||||
public RadialMenu(String title, String desc, String[] optionTexts, Image[] optionIcons){
|
||||
super(0, 0, Chrome.get(Chrome.Type.BLANK));
|
||||
remove(shadow);
|
||||
|
||||
int size = SPDSettings.interfaceSize() == 0 ? 140 : 200;
|
||||
resize(size, size);
|
||||
|
||||
slots = optionTexts.length;
|
||||
center = new PointF(size/2, size/2);
|
||||
int length = SPDSettings.interfaceSize() == 0 ? 57 : 80;
|
||||
|
||||
selectionArc = new CircleArc(120/slots, size/2 - 1);
|
||||
selectionArc.color(0xFFFFFF, false);
|
||||
selectionArc.alpha(0.6f);
|
||||
selectionArc.setSweep(1f/slots);
|
||||
selectionArc.point(center);
|
||||
selectionArc.visible = false;
|
||||
add(selectionArc);
|
||||
|
||||
Image outerBG = getBGTexture(size, false);
|
||||
add(outerBG);
|
||||
|
||||
texts = optionTexts;
|
||||
icons = optionIcons;
|
||||
|
||||
for (int i = 0; i < slots; i++){
|
||||
|
||||
PointF iconCenter = new PointF().polar((PointF.PI2/slots * i)-PointF.PI/2, length);
|
||||
iconCenter.offset(center);
|
||||
optionIcons[i].x = iconCenter.x - optionIcons[i].width()/2f;
|
||||
optionIcons[i].y = iconCenter.y - optionIcons[i].height()/2f;
|
||||
PixelScene.align(optionIcons[i]);
|
||||
optionIcons[i].alpha(0.4f);
|
||||
add(optionIcons[i]);
|
||||
|
||||
ColorBlock sep = new ColorBlock(size/2 - 2, 1, 0xFF000000);
|
||||
sep.x = center.x;
|
||||
sep.y = center.y;
|
||||
sep.angle = (360f/slots * i) + selectionArc.getSweep()*180 - 90;
|
||||
addToFront(sep);
|
||||
|
||||
}
|
||||
|
||||
Image innerBG = getBGTexture(size, true);
|
||||
innerBG.x = (width - innerBG.width) / 2;
|
||||
innerBG.y = (height - innerBG.height) / 2;
|
||||
add(innerBG);
|
||||
|
||||
descTxt = PixelScene.renderTextBlock(desc, 6);
|
||||
descTxt.align(RenderedTextBlock.CENTER_ALIGN);
|
||||
descTxt.maxWidth(SPDSettings.interfaceSize() == 0 ? 80 : 100);
|
||||
descTxt.setPos(center.x - descTxt.width()/2, center.y - descTxt.height()/4);
|
||||
add(descTxt);
|
||||
|
||||
titleTxt = PixelScene.renderTextBlock(title, 9);
|
||||
titleTxt.setPos(center.x - titleTxt.width()/2f, descTxt.top() - titleTxt.height() - 6);
|
||||
PixelScene.align(titleTxt);
|
||||
titleTxt.hardlight(TITLE_COLOR);
|
||||
add(titleTxt);
|
||||
|
||||
Cursor.captureCursor(true);
|
||||
|
||||
Button selector = new Button(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
if (selectedIdx != -1){
|
||||
hide();
|
||||
onSelect(selectedIdx, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onLongClick() {
|
||||
if (selectedIdx != -1){
|
||||
hide();
|
||||
onSelect(selectedIdx, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightClick() {
|
||||
super.onRightClick();
|
||||
if (selectedIdx != -1){
|
||||
hide();
|
||||
onSelect(selectedIdx, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
selector.setRect(0, 0, size, size);
|
||||
add(selector);
|
||||
|
||||
}
|
||||
|
||||
public void onSelect(int idx, boolean alt){}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
Cursor.captureCursor(false);
|
||||
}
|
||||
|
||||
//the mouse has a hidden position in a 20-pixel radius circle, helps make selection feel more natural
|
||||
private PointF mousePos = new PointF();
|
||||
private boolean first = true; //ignore the first mouse input as it's caused by hiding mouse
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
super.update();
|
||||
|
||||
PointF movement = Cursor.getCursorDelta();
|
||||
//40% deadzone for controller input here
|
||||
if (Math.abs(ControllerHandler.rightStickPosition.x) >= 0.4f
|
||||
|| Math.abs(ControllerHandler.rightStickPosition.y) >= 0.4f){
|
||||
movement.x = ControllerHandler.rightStickPosition.x;
|
||||
movement.y = ControllerHandler.rightStickPosition.y;
|
||||
first = false;
|
||||
} else if (movement.length() != 0 && !first) {
|
||||
mousePos.offset(movement);
|
||||
if (mousePos.length() > PixelScene.defaultZoom*20) {
|
||||
mousePos.invScale(mousePos.length() / (PixelScene.defaultZoom*20));
|
||||
}
|
||||
movement = mousePos;
|
||||
}
|
||||
|
||||
if (movement.length() != 0) {
|
||||
if (first){
|
||||
first = false;
|
||||
return;
|
||||
}
|
||||
|
||||
targetAngle = PointF.angle(movement.x, movement.y) / PointF.G2R + 90;
|
||||
if (targetAngle < 0) targetAngle += 360f;
|
||||
|
||||
selectionArc.visible = true;
|
||||
selectionArc.angle = targetAngle + selectionArc.getSweep()*180;
|
||||
|
||||
int newSelect = (int) Math.round((targetAngle) / (360f/slots));
|
||||
if (newSelect >= slots) newSelect = 0;
|
||||
|
||||
if (newSelect != selectedIdx) {
|
||||
selectedIdx = newSelect;
|
||||
for (int i = 0; i < slots; i++) {
|
||||
if (i == selectedIdx) {
|
||||
icons[i].alpha(1f);
|
||||
titleTxt.text(texts[i]);
|
||||
titleTxt.setPos(center.x - titleTxt.width()/2f, descTxt.top() - titleTxt.height() - 6);
|
||||
PixelScene.align(titleTxt);
|
||||
} else {
|
||||
icons[i].alpha(0.4f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Image getBGTexture(int size, boolean inner){
|
||||
if (size >= 200){
|
||||
if (!inner) return new Image(Assets.Interfaces.RADIAL_MENU, 0, 0, 200, 200);
|
||||
else return new Image(Assets.Interfaces.RADIAL_MENU, 340, 0, 120, 120);
|
||||
} else {
|
||||
if (!inner) return new Image(Assets.Interfaces.RADIAL_MENU, 200, 0, 140, 140);
|
||||
else return new Image(Assets.Interfaces.RADIAL_MENU, 340, 120, 90, 90);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,17 +26,25 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDAction;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LostInventory;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuickBag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndUseItem;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.input.GameAction;
|
||||
import com.watabou.input.KeyBindings;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Gizmo;
|
||||
@@ -46,6 +54,8 @@ import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Toolbar extends Component {
|
||||
|
||||
private Tool btnWait;
|
||||
@@ -90,6 +100,99 @@ public class Toolbar extends Component {
|
||||
for (int i = 0; i < btnQuick.length; i++){
|
||||
add( btnQuick[i] = new QuickslotTool(64, 0, 22, 24, i) );
|
||||
}
|
||||
|
||||
//hidden button for quickslot selector keybind
|
||||
add(new Button(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if (QuickSlotButton.targetingSlot != -1){
|
||||
int cell = QuickSlotButton.autoAim(QuickSlotButton.lastTarget, Dungeon.quickslot.getItem(QuickSlotButton.targetingSlot));
|
||||
|
||||
if (cell != -1){
|
||||
GameScene.handleCell(cell);
|
||||
} else {
|
||||
//couldn't auto-aim, just target the position and hope for the best.
|
||||
GameScene.handleCell( QuickSlotButton.lastTarget.pos );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Dungeon.hero.ready && !GameScene.cancel()) {
|
||||
|
||||
String[] slotNames = new String[6];
|
||||
Image[] slotIcons = new Image[6];
|
||||
for (int i = 0; i < 6; i++){
|
||||
Item item = Dungeon.quickslot.getItem(i);
|
||||
|
||||
if (item != null && !Dungeon.quickslot.isPlaceholder(i) &&
|
||||
(Dungeon.hero.buff(LostInventory.class) == null || item.keptThoughLostInvent)){
|
||||
slotNames[i] = Messages.titleCase(item.name());
|
||||
slotIcons[i] = new ItemSprite(item);
|
||||
} else {
|
||||
slotNames[i] = Messages.get(Toolbar.class, "quickslot_assign");
|
||||
slotIcons[i] = new ItemSprite(ItemSpriteSheet.SOMETHING);
|
||||
}
|
||||
}
|
||||
|
||||
String info = "";
|
||||
if (ControllerHandler.controllerPointerActive()){
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.LEFT_CLICK, true)) + ": " + Messages.get(Toolbar.class, "quickslot_select") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.RIGHT_CLICK, true)) + ": " + Messages.get(Toolbar.class, "quickslot_assign") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, true)) + ": " + Messages.get(Toolbar.class, "quickslot_cancel");
|
||||
} else {
|
||||
info += Messages.get(WndKeyBindings.class, SPDAction.LEFT_CLICK.name()) + ": " + Messages.get(Toolbar.class, "quickslot_select") + "\n";
|
||||
info += Messages.get(WndKeyBindings.class, SPDAction.RIGHT_CLICK.name()) + ": " + Messages.get(Toolbar.class, "quickslot_assign") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, false)) + ": " + Messages.get(Toolbar.class, "quickslot_cancel");
|
||||
}
|
||||
|
||||
GameScene.show(new RadialMenu(Messages.get(Toolbar.class, "quickslot_prompt"), info, slotNames, slotIcons) {
|
||||
@Override
|
||||
public void onSelect(int idx, boolean alt) {
|
||||
Item item = Dungeon.quickslot.getItem(idx);
|
||||
|
||||
if (item == null || Dungeon.quickslot.isPlaceholder(idx)
|
||||
|| (Dungeon.hero.buff(LostInventory.class) != null && !item.keptThoughLostInvent)
|
||||
|| alt){
|
||||
//TODO would be nice to use a radial menu for this too
|
||||
// Also a bunch of code could be moved out of here into subclasses of RadialMenu
|
||||
GameScene.selectItem(new WndBag.ItemSelector() {
|
||||
@Override
|
||||
public String textPrompt() {
|
||||
return Messages.get(QuickSlotButton.class, "select_item");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean itemSelectable(Item item) {
|
||||
return item.defaultAction != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelect(Item item) {
|
||||
if (item != null) {
|
||||
Dungeon.quickslot.setSlot( idx , item );
|
||||
QuickSlotButton.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
item.execute(Dungeon.hero);
|
||||
if (item.usesTargeting) {
|
||||
QuickSlotButton.useTargeting(idx);
|
||||
}
|
||||
}
|
||||
super.onSelect(idx, alt);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameAction keyAction() {
|
||||
if (btnWait.active) return SPDAction.QUICKSLOT_SELECTOR;
|
||||
else return null;
|
||||
}
|
||||
});
|
||||
|
||||
add(btnWait = new Tool(24, 0, 20, 26) {
|
||||
@Override
|
||||
@@ -119,6 +222,7 @@ public class Toolbar extends Component {
|
||||
}
|
||||
});
|
||||
|
||||
//hidden button for rest keybind
|
||||
add(new Button(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
@@ -135,6 +239,7 @@ public class Toolbar extends Component {
|
||||
}
|
||||
});
|
||||
|
||||
//hidden button for wait / pickup keybind
|
||||
add(new Button(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
@@ -253,6 +358,98 @@ public class Toolbar extends Component {
|
||||
}
|
||||
});
|
||||
|
||||
//hidden button for inventory selector keybind
|
||||
add(new Button(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if (Dungeon.hero.ready && !GameScene.cancel()) {
|
||||
ArrayList<Bag> bags = Dungeon.hero.belongings.getBags();
|
||||
String[] names = new String[bags.size()];
|
||||
Image[] images = new Image[bags.size()];
|
||||
for (int i = 0; i < bags.size(); i++){
|
||||
names[i] = Messages.titleCase(bags.get(i).name());
|
||||
images[i] = new ItemSprite(bags.get(i));
|
||||
}
|
||||
String info = "";
|
||||
if (ControllerHandler.controllerPointerActive()){
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.LEFT_CLICK, true)) + ": " + Messages.get(Toolbar.class, "container_select") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, true)) + ": " + Messages.get(Toolbar.class, "container_cancel");
|
||||
} else {
|
||||
info += Messages.get(WndKeyBindings.class, SPDAction.LEFT_CLICK.name()) + ": " + Messages.get(Toolbar.class, "container_select") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, false)) + ": " + Messages.get(Toolbar.class, "container_cancel");
|
||||
}
|
||||
|
||||
GameScene.show(new RadialMenu(Messages.get(Toolbar.class, "container_prompt"), info, names, images){
|
||||
@Override
|
||||
public void onSelect(int idx, boolean alt) {
|
||||
super.onSelect(idx, alt);
|
||||
Bag bag = bags.get(idx);
|
||||
ArrayList<Item> items = (ArrayList<Item>) bag.items.clone();
|
||||
|
||||
for(Item i : bag.items){
|
||||
if (i instanceof Bag) items.remove(i);
|
||||
if (Dungeon.hero.buff(LostInventory.class) != null && !i.keptThoughLostInvent) items.remove(i);
|
||||
}
|
||||
|
||||
if (idx == 0){
|
||||
Belongings b = Dungeon.hero.belongings;
|
||||
if (b.ring() != null) items.add(0, b.ring());
|
||||
if (b.misc() != null) items.add(0, b.misc());
|
||||
if (b.artifact() != null) items.add(0, b.artifact());
|
||||
if (b.armor() != null) items.add(0, b.armor());
|
||||
if (b.weapon() != null) items.add(0, b.weapon());
|
||||
}
|
||||
|
||||
if (items.size() == 0){
|
||||
GameScene.show(new WndMessage(Messages.get(Toolbar.class, "container_empty")));
|
||||
return;
|
||||
}
|
||||
|
||||
String[] itemNames = new String[items.size()];
|
||||
Image[] itemIcons = new Image[items.size()];
|
||||
for (int i = 0; i < items.size(); i++){
|
||||
itemNames[i] = Messages.titleCase(items.get(i).name());
|
||||
itemIcons[i] = new ItemSprite(items.get(i));
|
||||
}
|
||||
|
||||
String info = "";
|
||||
if (ControllerHandler.controllerPointerActive()){
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.LEFT_CLICK, true)) + ": " + Messages.get(Toolbar.class, "item_select") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.RIGHT_CLICK, true)) + ": " + Messages.get(Toolbar.class, "item_use") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, false)) + ": " + Messages.get(Toolbar.class, "item_cancel");
|
||||
} else {
|
||||
info += Messages.get(WndKeyBindings.class, SPDAction.LEFT_CLICK.name()) + ": " + Messages.get(Toolbar.class, "item_select") + "\n";
|
||||
info += Messages.get(WndKeyBindings.class, SPDAction.RIGHT_CLICK.name()) + ": " + Messages.get(Toolbar.class, "item_use") + "\n";
|
||||
info += KeyBindings.getKeyName(KeyBindings.getFirstKeyForAction(GameAction.BACK, false)) + ": " + Messages.get(Toolbar.class, "item_cancel");
|
||||
}
|
||||
|
||||
GameScene.show(new RadialMenu(Messages.get(Toolbar.class, "item_prompt"), info, itemNames, itemIcons){
|
||||
@Override
|
||||
public void onSelect(int idx, boolean alt) {
|
||||
super.onSelect(idx, alt);
|
||||
Item item = items.get(idx);
|
||||
if (alt && item.defaultAction != null) {
|
||||
item.execute(Dungeon.hero);
|
||||
if (item.usesTargeting) {
|
||||
QuickSlotButton.useTargeting(idx);
|
||||
}
|
||||
} else {
|
||||
Game.scene().addToFront(new WndUseItem(null, item));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameAction keyAction() {
|
||||
if (btnWait.active) return SPDAction.INVENTORY_SELECTOR;
|
||||
else return null;
|
||||
}
|
||||
});
|
||||
|
||||
add(pickedUp = new PickedUpItem());
|
||||
}
|
||||
|
||||
|
||||
@@ -84,16 +84,43 @@ public class v1_X_Changes {
|
||||
changes.hardlight(Window.TITLE_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes = new ChangeInfo("", false, null);
|
||||
changes = new ChangeInfo("BETA-3", false, null);
|
||||
changes.hardlight(Window.TITLE_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes.addButton( new ChangeButton(Icons.get(Icons.SHPX), "To-Do",
|
||||
"I'm going to round the beta out and try to get it released early/mid next week. Because of that some of these things may be handled in patches:\n\n" +
|
||||
"_-_ Additional enemy info on the top-left of the screen on full UI mode\n" +
|
||||
"_-_ Improvements to some of the game's interfaces on full UI mode\n" +
|
||||
"_-_ Translation work, and updated translators credits.\n" +
|
||||
"_-_ Fixes for any bugs that get reported"));
|
||||
|
||||
changes.addButton( new ChangeButton(Icons.get(Icons.CONTROLLER), "UI/UX Improvements",
|
||||
"A new radial menu system has been added, primarily for controller users! This should make using quickslots and the inventory much faster.\n\n" +
|
||||
"These new menus also free up a bunch of buttons, so default controller button mappings have been reworked.\n\n" +
|
||||
"A few other key binding actions have been adjusted as well, including a combo 'wait/loot item' action, and scrolling up/down using the zoom actions."));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.PREFS), Messages.get(ChangesScene.class, "misc"),
|
||||
"_-_ Levels are now cleared during ascension just before the hero returns to them. This prevents difficulty spikes if floors were left full of enemies. Ascension enemy spawn rates slightly increased to compensate\n\n" +
|
||||
"_-_ Nearby enemies are no longer constantly drawn to the hero's position during the ascension challenge"));
|
||||
|
||||
changes.addButton(new ChangeButton(new Image(Assets.Sprites.SPINNER, 144, 0, 16, 16), Messages.get(ChangesScene.class, "bugfixes"),
|
||||
"Fixed (Caused by BETA)\n" +
|
||||
"_-_ Various rare crash bugs\n" +
|
||||
"_-_ Various minor visual and textual bugs\n" +
|
||||
"_-_ Daily run history being lost in some cases\n" +
|
||||
"_-_ Higher tier 'score chaser' badges not unlocking lower tier ones\n" +
|
||||
"_-_ 'Friendly Fire' badge not being awarded by wand of corrosion\n\n" +
|
||||
"Fixed (Existed Prior to BETA)\n" +
|
||||
"_-_ Beacon of returning not working at all in boss arenas\n" +
|
||||
"_-_ Various 'cause of death' badges not being awarded if death occurred with an ankh."));
|
||||
|
||||
changes = new ChangeInfo("BETA-2", false, null);
|
||||
changes.hardlight(Window.TITLE_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes.addButton(new ChangeButton(new Image(Assets.Sprites.SPINNER, 144, 0, 16, 16), Messages.get(ChangesScene.class, "bugfixes"),
|
||||
"Fixed (Caused by Beta)\n" +
|
||||
"Fixed (Caused by BETA)\n" +
|
||||
"_-_ Various rare crash issues\n" +
|
||||
"_-_ Daily runs preventing regular runs from being started\n" +
|
||||
"_-_ Duplicate crystal keys from pit rooms\n" +
|
||||
@@ -108,15 +135,6 @@ public class v1_X_Changes {
|
||||
"_-_ XX days after Shattered v1.2.0\n" +
|
||||
"Expect dev commentary here in the future."));*/
|
||||
|
||||
changes.addButton( new ChangeButton(Icons.get(Icons.SHPX), "To-Do",
|
||||
"There are still a few bits and pieces left to finish up before v1.3 is released, mainly focused on interface work:\n\n" +
|
||||
"_-_ A new radial selection menu to make using quickslots and the inventory easier on controller\n" +
|
||||
"_-_ Improvements to default controller bindings, and some improved button functionality\n" +
|
||||
"_-_ Additional enemy info on the top-left of the screen on full UI mode\n" +
|
||||
"_-_ Improvements to some of the game's interfaces on full UI mode\n" +
|
||||
"_-_ Translation work, from volunteers on the game's Transifex project.\n" +
|
||||
"_-_ Fixes for any bugs that get reported"));
|
||||
|
||||
Image ic = Icons.get(Icons.SEED);
|
||||
ic.hardlight(1f, 1.5f, 0.67f);
|
||||
changes.addButton( new ChangeButton(ic, "Seeded Runs!",
|
||||
|
||||
@@ -134,19 +134,28 @@ public class WndKeyBindings extends Window {
|
||||
bindingsList.add(sep);
|
||||
}
|
||||
|
||||
for (GameAction action : GameAction.allActions()){
|
||||
LinkedHashMap<Integer, GameAction> defaults = controller ? SPDAction.getControllerDefaults() : SPDAction.getDefaults();
|
||||
|
||||
ArrayList<GameAction> actionList = GameAction.allActions();
|
||||
for (GameAction action : actionList.toArray(new GameAction[0])) {
|
||||
//start at 1. No bindings for NONE
|
||||
if (action.code() < 1) continue;
|
||||
if (action.code() < 1) {
|
||||
actionList.remove(action);
|
||||
|
||||
//mouse bindings are only available to controllers
|
||||
if ((action == GameAction.LEFT_CLICK
|
||||
} else if ((action == GameAction.LEFT_CLICK
|
||||
|| action == GameAction.RIGHT_CLICK
|
||||
|| action == GameAction.MIDDLE_CLICK) && !controller){
|
||||
continue;
|
||||
|| action == GameAction.MIDDLE_CLICK) && !controller) {
|
||||
actionList.remove(action);
|
||||
|
||||
//actions with no default binding are moved to the end of the list
|
||||
} else if (!defaults.containsValue(action)){
|
||||
actionList.remove(action);
|
||||
actionList.add(action);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO probably exclude some binding for controllers, and adjust default mappings
|
||||
|
||||
for (GameAction action : actionList){
|
||||
BindingItem item = new BindingItem(action);
|
||||
item.setRect(0, y, WIDTH, BindingItem.HEIGHT);
|
||||
bindingsList.addToBack(item);
|
||||
|
||||
Reference in New Issue
Block a user