V0.1.0 Partial Commit

changed package and application names to differentiate from main PD
release
This commit is contained in:
Evan Debenham
2014-08-03 14:46:22 -04:00
parent 65dd9c2dc0
commit aed303672a
474 changed files with 3468 additions and 3458 deletions
@@ -0,0 +1,65 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Game;
import com.watabou.noosa.SkinnedBlock;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
public class Archs extends Component {
private static final float SCROLL_SPEED = 20f;
private SkinnedBlock arcsBg;
private SkinnedBlock arcsFg;
public boolean reversed = false;
@Override
protected void createChildren() {
arcsBg = new SkinnedBlock( 1, 1, Assets.ARCS_BG );
add( arcsBg );
arcsFg = new SkinnedBlock( 1, 1, Assets.ARCS_FG );
add( arcsFg );
}
@Override
protected void layout() {
arcsBg.size( width, height );
arcsBg.offset( arcsBg.texture.width / 4 - (width % arcsBg.texture.width) / 2, 0 );
arcsFg.size( width, height );
arcsFg.offset( arcsFg.texture.width / 4 - (width % arcsFg.texture.width) / 2, 0 );
}
@Override
public void update() {
super.update();
float shift = Game.elapsed * SCROLL_SPEED;
if (reversed) {
shift = -shift;
}
arcsBg.offset( 0, shift );
arcsFg.offset( 0, shift * 2 );
}
}
@@ -0,0 +1,167 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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 java.util.ArrayList;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.watabou.utils.Random;
public class AttackIndicator extends Tag {
private static final float ENABLED = 1.0f;
private static final float DISABLED = 0.3f;
private static AttackIndicator instance;
private CharSprite sprite = null;
private static Mob lastTarget = null;
private ArrayList<Mob> candidates = new ArrayList<Mob>();
public AttackIndicator() {
super( DangerIndicator.COLOR );
instance = this;
setSize( 24, 24 );
visible( false );
enable( false );
}
@Override
protected void createChildren() {
super.createChildren();
}
@Override
protected void layout() {
super.layout();
if (sprite != null) {
sprite.x = x + (width - sprite.width()) / 2;
sprite.y = y + (height - sprite.height()) / 2;
PixelScene.align( sprite );
}
}
@Override
public void update() {
super.update();
if (Dungeon.hero.isAlive()) {
if (!Dungeon.hero.ready) {
enable( false );
}
} else {
visible( false );
enable( false );
}
}
private void checkEnemies() {
int heroPos = Dungeon.hero.pos;
candidates.clear();
int v = Dungeon.hero.visibleEnemies();
for (int i=0; i < v; i++) {
Mob mob = Dungeon.hero.visibleEnemy( i );
if (Level.adjacent( heroPos, mob.pos )) {
candidates.add( mob );
}
}
if (!candidates.contains( lastTarget )) {
if (candidates.isEmpty()) {
lastTarget = null;
} else {
lastTarget = Random.element( candidates );
updateImage();
flash();
}
} else {
if (!bg.visible) {
flash();
}
}
visible( lastTarget != null );
enable( bg.visible );
}
private void updateImage() {
if (sprite != null) {
sprite.killAndErase();
sprite = null;
}
try {
sprite = lastTarget.spriteClass.newInstance();
sprite.idle();
sprite.paused = true;
add( sprite );
sprite.x = x + (width - sprite.width()) / 2 + 1;
sprite.y = y + (height - sprite.height()) / 2;
PixelScene.align( sprite );
} catch (Exception e) {
}
}
private boolean enabled = true;
private void enable( boolean value ) {
enabled = value;
if (sprite != null) {
sprite.alpha( value ? ENABLED : DISABLED );
}
}
private void visible( boolean value ) {
bg.visible = value;
if (sprite != null) {
sprite.visible = value;
}
}
@Override
protected void onClick() {
if (enabled) {
Dungeon.hero.handle( lastTarget.pos );
}
}
public static void target( Char target ) {
lastTarget = (Mob)target;
instance.updateImage();
HealthIndicator.instance.target( target );
}
public static void updateState() {
instance.checkEnemies();
}
}
@@ -0,0 +1,122 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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 java.util.ArrayList;
import com.watabou.noosa.BitmapText;
import com.watabou.noosa.Game;
import com.watabou.noosa.Image;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.effects.BadgeBanner;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBadge;
public class BadgesList extends ScrollPane {
private ArrayList<ListItem> items = new ArrayList<ListItem>();
public BadgesList( boolean global ) {
super( new Component() );
for (Badges.Badge badge : Badges.filtered( global )) {
if (badge.image == -1) {
continue;
}
ListItem item = new ListItem( badge );
content.add( item );
items.add( item );
}
}
@Override
protected void layout() {
super.layout();
float pos = 0;
int size = items.size();
for (int i=0; i < size; i++) {
items.get( i ).setRect( 0, pos, width, ListItem.HEIGHT );
pos += ListItem.HEIGHT;
}
content.setSize( width, pos );
}
@Override
public void onClick( float x, float y ) {
int size = items.size();
for (int i=0; i < size; i++) {
if (items.get( i ).onClick( x, y )) {
break;
}
}
}
private class ListItem extends Component {
private static final float HEIGHT = 20;
private Badges.Badge badge;
private Image icon;
private BitmapText label;
public ListItem( Badges.Badge badge ) {
super();
this.badge = badge;
icon.copy( BadgeBanner.image( badge.image ));
label.text( badge.description );
}
@Override
protected void createChildren() {
icon = new Image();
add( icon );
label = PixelScene.createText( 6 );
add( label );
}
@Override
protected void layout() {
icon.x = x;
icon.y = PixelScene.align( y + (height - icon.height) / 2 );
label.x = icon.x + icon.width + 2;
label.y = PixelScene.align( y + (height - label.baseLine()) / 2 );
}
public boolean onClick( float x, float y ) {
if (inside( x, y )) {
Sample.INSTANCE.play( Assets.SND_CLICK, 0.7f, 0.7f, 1.2f );
Game.scene().add( new WndBadge( badge ) );
return true;
} else {
return false;
}
}
}
}
@@ -0,0 +1,101 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Game;
import com.watabou.noosa.Image;
public class Banner extends Image {
private enum State {
FADE_IN, STATIC, FADE_OUT
};
private State state;
private float time;
private int color;
private float fadeTime;
private float showTime;
public Banner( Image sample ) {
super();
copy( sample );
alpha( 0 );
}
public Banner( Object tx ) {
super( tx );
alpha( 0 );
}
public void show( int color, float fadeTime, float showTime ) {
this.color = color;
this.fadeTime = fadeTime;
this.showTime = showTime;
state = State.FADE_IN;
time = fadeTime;
}
public void show( int color, float fadeTime ) {
show( color, fadeTime, Float.MAX_VALUE );
}
@Override
public void update() {
super.update();
time -= Game.elapsed;
if (time >= 0) {
float p = time / fadeTime;
switch (state) {
case FADE_IN:
tint( color, p );
alpha( 1 - p );
break;
case STATIC:
break;
case FADE_OUT:
alpha( p );
break;
}
} else {
switch (state) {
case FADE_IN:
time = showTime;
state = State.STATIC;
break;
case STATIC:
time = fadeTime;
state = State.FADE_OUT;
break;
case FADE_OUT:
killAndErase();
break;
}
}
}
}
@@ -0,0 +1,143 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.tweeners.AlphaTweener;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.watabou.utils.SparseArray;
public class BuffIndicator extends Component {
public static final int NONE = -1;
public static final int MIND_VISION = 0;
public static final int LEVITATION = 1;
public static final int FIRE = 2;
public static final int POISON = 3;
public static final int PARALYSIS = 4;
public static final int HUNGER = 5;
public static final int STARVATION = 6;
public static final int SLOW = 7;
public static final int OOZE = 8;
public static final int AMOK = 9;
public static final int TERROR = 10;
public static final int ROOTS = 11;
public static final int INVISIBLE = 12;
public static final int SHADOWS = 13;
public static final int WEAKNESS = 14;
public static final int FROST = 15;
public static final int BLINDNESS = 16;
public static final int COMBO = 17;
public static final int FURY = 18;
public static final int HEALING = 19;
public static final int ARMOR = 20;
public static final int HEART = 21;
public static final int LIGHT = 22;
public static final int CRIPPLE = 23;
public static final int BARKSKIN = 24;
public static final int IMMUNITY = 25;
public static final int BLEEDING = 26;
public static final int MARK = 27;
public static final int DEFERRED = 28;
public static final int SIZE = 7;
private static BuffIndicator heroInstance;
private SmartTexture texture;
private TextureFilm film;
private SparseArray<Image> icons = new SparseArray<Image>();
private Char ch;
public BuffIndicator( Char ch ) {
super();
this.ch = ch;
if (ch == Dungeon.hero) {
heroInstance = this;
}
}
@Override
public void destroy() {
super.destroy();
if (this == heroInstance) {
heroInstance = null;
}
}
@Override
protected void createChildren() {
texture = TextureCache.get( Assets.BUFFS_SMALL );
film = new TextureFilm( texture, SIZE, SIZE );
}
@Override
protected void layout() {
clear();
SparseArray<Image> newIcons = new SparseArray<Image>();
for (Buff buff : ch.buffs()) {
int icon = buff.icon();
if (icon != NONE) {
Image img = new Image( texture );
img.frame( film.get( icon ) );
img.x = x + members.size() * (SIZE + 2);
img.y = y;
add( img );
newIcons.put( icon, img );
}
}
for (Integer key : icons.keyArray()) {
if (newIcons.get( key ) == null) {
Image icon = icons.get( key );
icon.origin.set( SIZE / 2 );
add( icon );
add( new AlphaTweener( icon, 0, 0.6f ) {
@Override
protected void updateValues( float progress ) {
super.updateValues( progress );
image.scale.set( 1 + 5 * progress );
};
} );
}
}
icons = newIcons;
}
public static void refreshHero() {
if (heroInstance != null) {
heroInstance.layout();
}
}
}
@@ -0,0 +1,38 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Image;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
public class BusyIndicator extends Image {
public BusyIndicator() {
super();
copy( Icons.BUSY.get() );
origin.set( width / 2, height / 2 );
angularSpeed = 720;
}
@Override
public void update() {
super.update();
visible = Dungeon.hero.isAlive() && !Dungeon.hero.ready;
}
}
@@ -0,0 +1,61 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.scenes.PixelScene;
public class CheckBox extends RedButton {
private boolean checked = false;
public CheckBox( String label ) {
super( label );
icon( Icons.get( Icons.UNCHECKED ) );
}
@Override
protected void layout() {
super.layout();
float margin = (height - text.baseLine()) / 2;
text.x = PixelScene.align( PixelScene.uiCamera, x + margin );
text.y = PixelScene.align( PixelScene.uiCamera, y + margin );
icon.x = PixelScene.align( PixelScene.uiCamera, x + width - margin - icon.width );
icon.y = PixelScene.align( PixelScene.uiCamera, y + (height - icon.height()) / 2 );
}
public boolean checked() {
return checked;
}
public void checked( boolean value ) {
if (checked != value) {
checked = value;
icon.copy( Icons.get( checked ? Icons.CHECKED : Icons.UNCHECKED ) );
}
}
@Override
protected void onClick() {
super.onClick();
checked( !checked );
}
}
@@ -0,0 +1,64 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Camera;
import com.watabou.noosa.Image;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap;
import com.watabou.utils.PointF;
public class Compass extends Image {
private static final float RAD_2_G = 180f / 3.1415926f;
private static final float RADIUS = 12;
private int cell;
private PointF cellCenter;
private PointF lastScroll = new PointF();
public Compass( int cell ) {
super();
copy( Icons.COMPASS.get() );
origin.set( width / 2, RADIUS );
this.cell = cell;
cellCenter = DungeonTilemap.tileCenterToWorld( cell );
visible = false;
}
@Override
public void update() {
super.update();
if (!visible) {
visible = Dungeon.level.visited[cell] || Dungeon.level.mapped[cell];
}
if (visible) {
PointF scroll = Camera.main.scroll;
if (!scroll.equals( lastScroll )) {
lastScroll.set( scroll );
PointF center = Camera.main.center().offset( scroll );
angle = (float)Math.atan2( cellCenter.x - center.x, center.y - cellCenter.y ) * RAD_2_G;
}
}
}
}
@@ -0,0 +1,104 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.BitmapText;
import com.watabou.noosa.Camera;
import com.watabou.noosa.Image;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
public class DangerIndicator extends Tag {
public static final int COLOR = 0xFF4C4C;
private BitmapText number;
private Image icon;
private int enemyIndex = 0;
private int lastNumber = -1;
public DangerIndicator() {
super( 0xFF4C4C );
setSize( 24, 16 );
visible = false;
}
@Override
protected void createChildren() {
super.createChildren();
number = new BitmapText( PixelScene.font1x );
add( number );
icon = Icons.SKULL.get();
add( icon );
}
@Override
protected void layout() {
super.layout();
icon.x = right() - 10;
icon.y = y + (height - icon.height) / 2;
placeNumber();
}
private void placeNumber() {
number.x = right() - 11 - number.width();
number.y = PixelScene.align( y + (height - number.baseLine()) / 2 );
}
@Override
public void update() {
if (Dungeon.hero.isAlive()) {
int v = Dungeon.hero.visibleEnemies();
if (v != lastNumber) {
lastNumber = v;
if (visible = (lastNumber > 0)) {
number.text( Integer.toString( lastNumber ) );
number.measure();
placeNumber();
flash();
}
}
} else {
visible = false;
}
super.update();
}
@Override
protected void onClick() {
Mob target = Dungeon.hero.visibleEnemy( enemyIndex++ );
HealthIndicator.instance.target( target == HealthIndicator.instance.target() ? null : target );
Camera.main.target = null;
Camera.main.focusOn( target.sprite );
}
}
@@ -0,0 +1,114 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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 java.util.regex.Pattern;
import com.watabou.noosa.BitmapTextMultiline;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
import com.watabou.utils.Signal;
public class GameLog extends Component implements Signal.Listener<String> {
private static final int MAX_MESSAGES = 3;
private static final Pattern PUNCTUATION = Pattern.compile( ".*[.,;?! ]$" );
private BitmapTextMultiline lastEntry;
private int lastColor;
public GameLog() {
super();
GLog.update.add( this );
newLine();
}
public void newLine() {
lastEntry = null;
}
@Override
public void onSignal( String text ) {
int color = CharSprite.DEFAULT;
if (text.startsWith( GLog.POSITIVE )) {
text = text.substring( GLog.POSITIVE.length() );
color = CharSprite.POSITIVE;
} else
if (text.startsWith( GLog.NEGATIVE )) {
text = text.substring( GLog.NEGATIVE.length() );
color = CharSprite.NEGATIVE;
} else
if (text.startsWith( GLog.WARNING )) {
text = text.substring( GLog.WARNING.length() );
color = CharSprite.WARNING;
} else
if (text.startsWith( GLog.HIGHLIGHT )) {
text = text.substring( GLog.HIGHLIGHT.length() );
color = CharSprite.NEUTRAL;
}
text = Utils.capitalize( text ) +
(PUNCTUATION.matcher( text ).matches() ? "" : ".");
if (lastEntry != null && color == lastColor) {
String lastMessage = lastEntry.text();
lastEntry.text( lastMessage.length() == 0 ? text : lastMessage + " " + text );
lastEntry.measure();
} else {
lastEntry = PixelScene.createMultiline( text, 6 );
lastEntry.maxWidth = (int)width;
lastEntry.measure();
lastEntry.hardlight( color );
lastColor = color;
add( lastEntry );
}
if (length > MAX_MESSAGES) {
remove( members.get( 0 ) );
}
layout();
}
@Override
protected void layout() {
float pos = y;
for (int i=length-1; i >= 0; i--) {
BitmapTextMultiline entry = (BitmapTextMultiline)members.get( i );
entry.x = x;
entry.y = pos - entry.height();
pos -= entry.height();
}
}
@Override
public void destroy() {
GLog.update.remove( this );
super.destroy();
}
}
@@ -0,0 +1,79 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.BitmapText;
import com.watabou.noosa.Game;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
public class GoldIndicator extends Component {
private static final float TIME = 2f;
private int lastValue = 0;
private BitmapText tf;
private float time;
@Override
protected void createChildren() {
tf = new BitmapText( PixelScene.font1x );
tf.hardlight( 0xFFFF00 );
add( tf );
visible = false;
}
@Override
protected void layout() {
tf.x = x + (width - tf.width()) / 2;
tf.y = bottom() - tf.height();
}
@Override
public void update() {
super.update();
if (visible) {
time -= Game.elapsed;
if (time > 0) {
tf.alpha( time > TIME / 2 ? 1f : time * 2 / TIME );
} else {
visible = false;
}
}
if (Dungeon.gold != lastValue) {
lastValue = Dungeon.gold;
tf.text( Integer.toString( lastValue ) );
tf.measure();
visible = true;
time = TIME;
layout();
}
}
}
@@ -0,0 +1,82 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.gltextures.TextureCache;
import com.watabou.noosa.Image;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
public class HealthIndicator extends Component {
private static final float HEIGHT = 2;
public static HealthIndicator instance;
private Char target;
private Image bg;
private Image level;
public HealthIndicator() {
super();
instance = this;
}
@Override
protected void createChildren() {
bg = new Image( TextureCache.createSolid( 0xFFcc0000 ) );
bg.scale.y = HEIGHT;
add( bg );
level = new Image( TextureCache.createSolid( 0xFF00cc00 ) );
level.scale.y = HEIGHT;
add( level );
}
@Override
public void update() {
super.update();
if (target != null && target.isAlive() && target.sprite.visible) {
CharSprite sprite = target.sprite;
bg.scale.x = sprite.width;
level.scale.x = sprite.width * target.HP / target.HT;
bg.x = level.x = sprite.x;
bg.y = level.y = sprite.y - HEIGHT - 1;
visible = true;
} else {
visible = false;
}
}
public void target( Char ch ) {
if (ch != null && ch.isAlive()) {
target = ch;
} else {
target = null;
}
}
public Char target() {
return target;
}
}
@@ -0,0 +1,152 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Image;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
public enum Icons {
SKULL,
BUSY,
COMPASS,
INFO,
PREFS,
WARNING,
TARGET,
MASTERY,
WATA,
WARRIOR,
MAGE,
ROGUE,
HUNTRESS,
CLOSE,
DEPTH,
SLEEP,
ALERT,
SUPPORT,
SUPPORTED,
BACKPACK,
SEED_POUCH,
SCROLL_HOLDER,
WAND_HOLSTER,
CHECKED,
UNCHECKED;
public Image get() {
return get( this );
}
public static Image get( Icons type ) {
Image icon = new Image( Assets.ICONS );
switch (type) {
case SKULL:
icon.frame( icon.texture.uvRect( 0, 0, 8, 8 ) );
break;
case BUSY:
icon.frame( icon.texture.uvRect( 8, 0, 16, 8 ) );
break;
case COMPASS:
icon.frame( icon.texture.uvRect( 0, 8, 7, 13 ) );
break;
case INFO:
icon.frame( icon.texture.uvRect( 16, 0, 30, 14 ) );
break;
case PREFS:
icon.frame( icon.texture.uvRect( 30, 0, 46, 16 ) );
break;
case WARNING:
icon.frame( icon.texture.uvRect( 46, 0, 58, 12 ) );
break;
case TARGET:
icon.frame( icon.texture.uvRect( 0, 13, 16, 29 ) );
break;
case MASTERY:
icon.frame( icon.texture.uvRect( 16, 14, 30, 28 ) );
break;
case WATA:
icon.frame( icon.texture.uvRect( 30, 16, 45, 26 ) );
break;
case WARRIOR:
icon.frame( icon.texture.uvRect( 0, 29, 16, 45 ) );
break;
case MAGE:
icon.frame( icon.texture.uvRect( 16, 29, 32, 45 ) );
break;
case ROGUE:
icon.frame( icon.texture.uvRect( 32, 29, 48, 45 ) );
break;
case HUNTRESS:
icon.frame( icon.texture.uvRect( 48, 29, 64, 45 ) );
break;
case CLOSE:
icon.frame( icon.texture.uvRect( 0, 45, 13, 58 ) );
break;
case DEPTH:
icon.frame( icon.texture.uvRect( 45, 12, 54, 20 ) );
break;
case SLEEP:
icon.frame( icon.texture.uvRect( 13, 45, 22, 53 ) );
break;
case ALERT:
icon.frame( icon.texture.uvRect( 22, 45, 30, 53 ) );
break;
case SUPPORT:
icon.frame( icon.texture.uvRect( 30, 45, 46, 61 ) );
break;
case SUPPORTED:
icon.frame( icon.texture.uvRect( 46, 45, 62, 61 ) );
break;
case BACKPACK:
icon.frame( icon.texture.uvRect( 58, 0, 68, 10 ) );
break;
case SCROLL_HOLDER:
icon.frame( icon.texture.uvRect( 68, 0, 78, 10 ) );
break;
case SEED_POUCH:
icon.frame( icon.texture.uvRect( 78, 0, 88, 10 ) );
break;
case WAND_HOLSTER:
icon.frame( icon.texture.uvRect( 88, 0, 98, 10 ) );
break;
case CHECKED:
icon.frame( icon.texture.uvRect( 54, 12, 66, 24 ) );
break;
case UNCHECKED:
icon.frame( icon.texture.uvRect( 66, 12, 78, 24 ) );
break;
}
return icon;
}
public static Image get( HeroClass cl ) {
switch (cl) {
case WARRIOR:
return get( WARRIOR );
case MAGE:
return get( MAGE );
case ROGUE:
return get( ROGUE );
case HUNTRESS:
return get( HUNTRESS );
default:
return null;
}
}
}
@@ -0,0 +1,195 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.BitmapText;
import com.watabou.noosa.ui.Button;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
public class ItemSlot extends Button {
public static final int DEGRADED = 0xFF4444;
public static final int UPGRADED = 0x44FF44;
public static final int WARNING = 0xFF8800;
private static final float ENABLED = 1.0f;
private static final float DISABLED = 0.3f;
protected ItemSprite icon;
protected BitmapText topLeft;
protected BitmapText topRight;
protected BitmapText bottomRight;
private static final String TXT_STRENGTH = ":%d";
private static final String TXT_TYPICAL_STR = "%d?";
private static final String TXT_LEVEL = "%+d";
private static final String TXT_CURSED = "";
// Special items for containers
public static final Item CHEST = new Item() {
public int image() { return ItemSpriteSheet.CHEST; };
};
public static final Item LOCKED_CHEST = new Item() {
public int image() { return ItemSpriteSheet.LOCKED_CHEST; };
};
public static final Item TOMB = new Item() {
public int image() { return ItemSpriteSheet.TOMB; };
};
public static final Item SKELETON = new Item() {
public int image() { return ItemSpriteSheet.BONES; };
};
public ItemSlot() {
super();
}
public ItemSlot( Item item ) {
this();
item( item );
}
@Override
protected void createChildren() {
super.createChildren();
icon = new ItemSprite();
add( icon );
topLeft = new BitmapText( PixelScene.font1x );
add( topLeft );
topRight = new BitmapText( PixelScene.font1x );
add( topRight );
bottomRight = new BitmapText( PixelScene.font1x );
add( bottomRight );
}
@Override
protected void layout() {
super.layout();
icon.x = x + (width - icon.width) / 2;
icon.y = y + (height - icon.height) / 2;
if (topLeft != null) {
topLeft.x = x;
topLeft.y = y;
}
if (topRight != null) {
topRight.x = x + (width - topRight.width());
topRight.y = y;
}
if (bottomRight != null) {
bottomRight.x = x + (width - bottomRight.width());
bottomRight.y = y + (height - bottomRight.height());
}
}
public void item( Item item ) {
if (item == null) {
active = false;
icon.visible = topLeft.visible = topRight.visible = bottomRight.visible = false;
} else {
active = true;
icon.visible = topLeft.visible = topRight.visible = bottomRight.visible = true;
icon.view( item.image(), item.glowing() );
topLeft.text( item.status() );
boolean isArmor = item instanceof Armor;
boolean isWeapon = item instanceof Weapon;
if (isArmor || isWeapon) {
if (item.levelKnown || (isWeapon && !(item instanceof MeleeWeapon))) {
int str = isArmor ? ((Armor)item).STR : ((Weapon)item).STR;
topRight.text( Utils.format( TXT_STRENGTH, str ) );
if (str > Dungeon.hero.STR()) {
topRight.hardlight( DEGRADED );
} else {
topRight.resetColor();
}
} else {
topRight.text( Utils.format( TXT_TYPICAL_STR, isArmor ?
((Armor)item).typicalSTR() :
((MeleeWeapon)item).typicalSTR() ) );
topRight.hardlight( WARNING );
}
topRight.measure();
} else {
topRight.text( null );
}
int level = item.visiblyUpgraded();
if (level != 0 || (item.cursed && item.cursedKnown)) {
bottomRight.text( item.levelKnown ? Utils.format( TXT_LEVEL, level ) : TXT_CURSED );
bottomRight.measure();
bottomRight.hardlight( level > 0 ? UPGRADED : DEGRADED );
} else {
bottomRight.text( null );
}
layout();
}
}
public void enable( boolean value ) {
active = value;
float alpha = value ? ENABLED : DISABLED;
icon.alpha( alpha );
topLeft.alpha( alpha );
topRight.alpha( alpha );
bottomRight.alpha( alpha );
}
public void showParams( boolean value ) {
if (value) {
add( topRight );
add( bottomRight );
} else {
remove( topRight );
remove( bottomRight );
}
}
}
@@ -0,0 +1,93 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
public class LootIndicator extends Tag {
private ItemSlot slot;
private Item lastItem = null;
private int lastQuantity = 0;
public LootIndicator() {
super( 0x1F75CC );
setSize( 24, 22 );
visible = false;
}
@Override
protected void createChildren() {
super.createChildren();
slot = new ItemSlot() {
protected void onClick() {
Dungeon.hero.handle( Dungeon.hero.pos );
};
};
slot.showParams( false );
add( slot );
}
@Override
protected void layout() {
super.layout();
slot.setRect( x + 2, y + 3, width - 2, height - 6 );
}
@Override
public void update() {
if (Dungeon.hero.ready) {
Heap heap = Dungeon.level.heaps.get( Dungeon.hero.pos );
if (heap != null) {
Item item =
heap.type == Heap.Type.CHEST ? ItemSlot.CHEST :
heap.type == Heap.Type.LOCKED_CHEST ? ItemSlot.LOCKED_CHEST :
heap.type == Heap.Type.TOMB ? ItemSlot.TOMB :
heap.type == Heap.Type.SKELETON ? ItemSlot.SKELETON :
heap.peek();
if (item != lastItem || item.quantity() != lastQuantity) {
lastItem = item;
lastQuantity = item.quantity();
slot.item( item );
flash();
}
visible = true;
} else {
lastItem = null;
visible = false;
}
}
slot.enable( visible && Dungeon.hero.ready );
super.update();
}
}
@@ -0,0 +1,68 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Image;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.ui.Button;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndSettings;
public class PrefsButton extends Button {
private Image image;
public PrefsButton() {
super();
width = image.width;
height = image.height;
}
@Override
protected void createChildren() {
super.createChildren();
image = Icons.PREFS.get();
add( image );
}
@Override
protected void layout() {
super.layout();
image.x = x;
image.y = y;
}
@Override
protected void onTouchDown() {
image.brightness( 1.5f );
Sample.INSTANCE.play( Assets.SND_CLICK );
}
@Override
protected void onTouchUp() {
image.resetColor();
}
@Override
protected void onClick() {
parent.add( new WndSettings( false ) );
}
}
@@ -0,0 +1,211 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Image;
import com.watabou.noosa.ui.Button;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
public class QuickSlot extends Button implements WndBag.Listener {
private static final String TXT_SELECT_ITEM = "Select an item for the quickslot";
private static QuickSlot instance;
private Item itemInSlot;
private ItemSlot slot;
private Image crossB;
private Image crossM;
private boolean targeting = false;
private Item lastItem = null;
private Char lastTarget= null;
public QuickSlot() {
super();
item( select() );
instance = this;
}
@Override
public void destroy() {
super.destroy();
instance = null;
lastItem = null;
lastTarget = null;
}
@Override
protected void createChildren() {
super.createChildren();
slot = new ItemSlot() {
@Override
protected void onClick() {
if (targeting) {
GameScene.handleCell( lastTarget.pos );
} else {
Item item = select();
if (item == lastItem) {
useTargeting();
} else {
lastItem = item;
}
item.execute( Dungeon.hero );
}
}
@Override
protected boolean onLongClick() {
return QuickSlot.this.onLongClick();
}
@Override
protected void onTouchDown() {
icon.lightness( 0.7f );
}
@Override
protected void onTouchUp() {
icon.resetColor();
}
};
add( slot );
crossB = Icons.TARGET.get();
crossB.visible = false;
add( crossB );
crossM = new Image();
crossM.copy( crossB );
}
@Override
protected void layout() {
super.layout();
slot.fill( this );
crossB.x = PixelScene.align( x + (width - crossB.width) / 2 );
crossB.y = PixelScene.align( y + (height - crossB.height) / 2 );
}
@Override
protected void onClick() {
GameScene.selectItem( this, WndBag.Mode.QUICKSLOT, TXT_SELECT_ITEM );
}
@Override
protected boolean onLongClick() {
GameScene.selectItem( this, WndBag.Mode.QUICKSLOT, TXT_SELECT_ITEM );
return true;
}
@SuppressWarnings("unchecked")
private static Item select() {
if (Dungeon.quickslot instanceof Item) {
return (Item)Dungeon.quickslot;
} else if (Dungeon.quickslot != null) {
Item item = Dungeon.hero.belongings.getItem( (Class<? extends Item>)Dungeon.quickslot );
return item != null ? item : Item.virtual( (Class<? extends Item>)Dungeon.quickslot );
} else {
return null;
}
}
@Override
public void onSelect( Item item ) {
if (item != null) {
Dungeon.quickslot = item.stackable ? item.getClass() : item;
refresh();
}
}
public void item( Item item ) {
slot.item( item );
itemInSlot = item;
enableSlot();
}
public void enable( boolean value ) {
active = value;
if (value) {
enableSlot();
} else {
slot.enable( false );
}
}
private void enableSlot() {
slot.enable(
itemInSlot != null &&
itemInSlot.quantity() > 0 &&
(Dungeon.hero.belongings.backpack.contains( itemInSlot ) || itemInSlot.isEquipped( Dungeon.hero )));
}
private void useTargeting() {
targeting = lastTarget != null && lastTarget.isAlive() && Dungeon.visible[lastTarget.pos];
if (targeting) {
if (Actor.all().contains( lastTarget )) {
lastTarget.sprite.parent.add( crossM );
crossM.point( DungeonTilemap.tileToWorld( lastTarget.pos ) );
crossB.visible = true;
} else {
lastTarget = null;
}
}
}
public static void refresh() {
if (instance != null) {
instance.item( select() );
}
}
public static void target( Item item, Char target ) {
if (item == instance.lastItem && target != Dungeon.hero) {
instance.lastTarget = target;
HealthIndicator.instance.target( target );
}
}
public static void cancel() {
if (instance != null && instance.targeting) {
instance.crossB.visible = false;
instance.crossM.remove();
instance.targeting = false;
}
}
}
@@ -0,0 +1,111 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.BitmapText;
import com.watabou.noosa.Image;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.ui.Button;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
public class RedButton extends Button {
protected NinePatch bg;
protected BitmapText text;
protected Image icon;
public RedButton( String label ) {
super();
text.text( label );
text.measure();
}
@Override
protected void createChildren() {
super.createChildren();
bg = Chrome.get( Chrome.Type.BUTTON );
add( bg );
text = PixelScene.createText( 9 );
add( text );
}
@Override
protected void layout() {
super.layout();
bg.x = x;
bg.y = y;
bg.size( width, height );
text.x = x + (int)(width - text.width()) / 2;
text.y = y + (int)(height - text.baseLine()) / 2;
if (icon != null) {
icon.x = x + text.x - icon.width() - 2;
icon.y = y + (height - icon.height()) / 2;
}
};
@Override
protected void onTouchDown() {
bg.brightness( 1.2f );
Sample.INSTANCE.play( Assets.SND_CLICK );
};
@Override
protected void onTouchUp() {
bg.resetColor();
};
public void enable( boolean value ) {
active = value;
text.alpha( value ? 1.0f : 0.3f );
}
public void text( String value ) {
text.text( value );
text.measure();
layout();
}
public void icon( Image icon ) {
if (this.icon != null) {
remove( this.icon );
}
this.icon = icon;
if (this.icon != null) {
add( this.icon );
layout();
}
}
public float reqWidth() {
return text.width() + 4;
}
public float reqHeight() {
return text.baseLine() + 4;
}
}
@@ -0,0 +1,149 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.input.Touchscreen.Touch;
import com.watabou.noosa.Camera;
import com.watabou.noosa.TouchArea;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.watabou.utils.Point;
import com.watabou.utils.PointF;
public class ScrollPane extends Component {
protected TouchController controller;
protected Component content;
protected float minX;
protected float minY;
protected float maxX;
protected float maxY;
public ScrollPane( Component content ) {
super();
this.content = content;
addToBack( content );
width = content.width();
height = content.height();
content.camera = new Camera( 0, 0, 1, 1, PixelScene.defaultZoom );
Camera.add( content.camera );
}
@Override
public void destroy() {
super.destroy();
Camera.remove( content.camera );
}
public void scrollTo( float x, float y ) {
content.camera.scroll.set( x, y );
}
@Override
protected void createChildren() {
controller = new TouchController();
add( controller );
}
@Override
protected void layout() {
content.setPos( 0, 0 );
controller.x = x;
controller.y = y;
controller.width = width;
controller.height = height;
Point p = camera().cameraToScreen( x, y );
Camera cs = content.camera;
cs.x = p.x;
cs.y = p.y;
cs.resize( (int)width, (int)height );
}
public Component content() {
return content;
}
public void onClick( float x, float y ) {
}
public class TouchController extends TouchArea {
private float dragThreshold;
public TouchController() {
super( 0, 0, 0, 0 );
dragThreshold = PixelScene.defaultZoom * 8;
}
@Override
protected void onClick( Touch touch ) {
if (dragging) {
dragging = false;
} else {
PointF p = content.camera.screenToCamera( (int)touch.current.x, (int)touch.current.y );
ScrollPane.this.onClick( p.x, p.y );
}
}
// true if dragging is in progress
private boolean dragging = false;
// last touch coords
private PointF lastPos = new PointF();
@Override
protected void onDrag( Touch t ) {
if (dragging) {
Camera c = content.camera;
c.scroll.offset( PointF.diff( lastPos, t.current ).invScale( c.zoom ) );
if (c.scroll.x + width > content.width()) {
c.scroll.x = content.width() - width;
}
if (c.scroll.x < 0) {
c.scroll.x = 0;
}
if (c.scroll.y + height > content.height()) {
c.scroll.y = content.height() - height;
}
if (c.scroll.y < 0) {
c.scroll.y = 0;
}
lastPos.set( t.current );
} else if (PointF.distance( t.current, t.start ) > dragThreshold) {
dragging = true;
lastPos.set( t.current );
}
}
}
}
@@ -0,0 +1,65 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.input.Touchscreen.Touch;
import com.watabou.noosa.Image;
import com.watabou.noosa.TouchArea;
import com.watabou.noosa.ui.Component;
public class SimpleButton extends Component {
private Image image;
public SimpleButton( Image image ) {
super();
this.image.copy( image );
width = image.width;
height = image.height;
}
@Override
protected void createChildren() {
image = new Image();
add( image );
add( new TouchArea( image ) {
@Override
protected void onTouchDown(Touch touch) {
image.brightness( 1.2f );
};
@Override
protected void onTouchUp(Touch touch) {
image.brightness( 1.0f );
};
@Override
protected void onClick( Touch touch ) {
SimpleButton.this.onClick();
};
} );
}
@Override
protected void layout() {
image.x = x;
image.y = y;
}
protected void onClick() {};
}
@@ -0,0 +1,199 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.input.Touchscreen.Touch;
import com.watabou.noosa.BitmapText;
import com.watabou.noosa.Camera;
import com.watabou.noosa.Image;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.TouchArea;
import com.watabou.noosa.particles.Emitter;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BloodParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndHero;
public class StatusPane extends Component {
private NinePatch shield;
private Image avatar;
private Emitter blood;
private int lastTier = 0;
private Image hp;
private Image exp;
private int lastLvl = -1;
private int lastKeys = -1;
private BitmapText level;
private BitmapText depth;
private BitmapText keys;
private DangerIndicator danger;
private LootIndicator loot;
private BuffIndicator buffs;
private Compass compass;
@Override
protected void createChildren() {
shield = new NinePatch( Assets.STATUS, 80, 0, 30, 0 );
add( shield );
add( new TouchArea( 0, 1, 30, 30 ) {
@Override
protected void onClick( Touch touch ) {
Image sprite = Dungeon.hero.sprite;
if (!sprite.isVisible()) {
Camera.main.focusOn( sprite );
}
GameScene.show( new WndHero() );
};
} );
avatar = HeroSprite.avatar( Dungeon.hero.heroClass, lastTier );
add( avatar );
blood = new Emitter();
blood.pos( avatar );
blood.pour( BloodParticle.FACTORY, 0.3f );
blood.autoKill = false;
blood.on = false;
add( blood );
compass = new Compass( Dungeon.level.exit );
add( compass );
hp = new Image( Assets.HP_BAR );
add( hp );
exp = new Image( Assets.XP_BAR );
add( exp );
level = new BitmapText( PixelScene.font1x );
level.hardlight( 0xFFEBA4 );
add( level );
depth = new BitmapText( Integer.toString( Dungeon.depth ), PixelScene.font1x );
depth.hardlight( 0xCACFC2 );
depth.measure();
add( depth );
Dungeon.hero.belongings.countIronKeys();
keys = new BitmapText( PixelScene.font1x );
keys.hardlight( 0xCACFC2 );
add( keys );
danger = new DangerIndicator();
add( danger );
loot = new LootIndicator();
add( loot );
buffs = new BuffIndicator( Dungeon.hero );
add( buffs );
}
@Override
protected void layout() {
height = 32;
shield.size( width, shield.height );
avatar.x = PixelScene.align( camera(), shield.x + 15 - avatar.width / 2 );
avatar.y = PixelScene.align( camera(), shield.y + 16 - avatar.height / 2 );
compass.x = avatar.x + avatar.width / 2 - compass.origin.x;
compass.y = avatar.y + avatar.height / 2 - compass.origin.y;
hp.x = 30;
hp.y = 3;
depth.x = width - 24 - depth.width();
depth.y = 6;
keys.y = 6;
danger.setPos( width - danger.width(), 20 );
loot.setPos( width - loot.width(), danger.bottom() + 2 );
buffs.setPos( 32, 11 );
}
@Override
public void update() {
super.update();
float health = (float)Dungeon.hero.HP / Dungeon.hero.HT;
if (health == 0) {
avatar.tint( 0x000000, 0.6f );
blood.on = false;
} else if (health < 0.25f) {
avatar.tint( 0xcc0000, 0.4f );
blood.on = true;
} else {
avatar.resetColor();
blood.on = false;
}
hp.scale.x = health;
exp.scale.x = (width / exp.width) * Dungeon.hero.exp / Dungeon.hero.maxExp();
if (Dungeon.hero.lvl != lastLvl) {
if (lastLvl != -1) {
Emitter emitter = (Emitter)recycle( Emitter.class );
emitter.revive();
emitter.pos( 27, 27 );
emitter.burst( Speck.factory( Speck.STAR ), 12 );
}
lastLvl = Dungeon.hero.lvl;
level.text( Integer.toString( lastLvl ) );
level.measure();
level.x = PixelScene.align( 27.0f - level.width() / 2 );
level.y = PixelScene.align( 27.5f - level.baseLine() / 2 );
}
int k = IronKey.curDepthQunatity;
if (k != lastKeys) {
lastKeys = k;
keys.text( Integer.toString( lastKeys ) );
keys.measure();
keys.x = width - 8 - keys.width();
}
int tier = Dungeon.hero.tier();
if (tier != lastTier) {
lastTier = tier;
avatar.copy( HeroSprite.avatar( Dungeon.hero.heroClass, tier ) );
}
}
}
@@ -0,0 +1,80 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Game;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.ui.Button;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
public class Tag extends Button {
private float r;
private float g;
private float b;
protected NinePatch bg;
protected float lightness = 0;
public Tag( int color ) {
super();
this.r = (color >> 16) / 255f;
this.g = ((color >> 8) & 0xFF) / 255f;
this.b = (color & 0xFF) / 255f;
}
@Override
protected void createChildren() {
super.createChildren();
bg = Chrome.get( Chrome.Type.TAG );
add( bg );
}
@Override
protected void layout() {
super.layout();
bg.x = x;
bg.y = y;
bg.size( width, height );
}
public void flash() {
lightness = 1f;
}
@Override
public void update() {
super.update();
if (visible && lightness > 0.5) {
if ((lightness -= Game.elapsed) > 0.5) {
bg.ra = bg.ga = bg.ba = 2 * lightness - 1;
bg.rm = 2 * r * (1 - lightness);
bg.gm = 2 * g * (1 - lightness);
bg.bm = 2 * b * (1 - lightness);
} else {
bg.hardlight( r, g, b );
}
}
}
}
@@ -0,0 +1,84 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.BitmapText;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
public class Toast extends Component {
private static final float MARGIN_HOR = 2;
private static final float MARGIN_VER = 2;
protected NinePatch bg;
protected SimpleButton close;
protected BitmapText text;
public Toast( String text ) {
super();
text( text );
width = this.text.width() + close.width() + bg.marginHor() + MARGIN_HOR * 3;
height = Math.max( this.text.height(), close.height() ) + bg.marginVer() + MARGIN_VER * 2;
}
@Override
protected void createChildren() {
super.createChildren();
bg = Chrome.get( Chrome.Type.TOAST_TR );
add( bg );
close = new SimpleButton( Icons.get( Icons.CLOSE ) ) {
protected void onClick() {
onClose();
};
};
add( close );
text = PixelScene.createText( 8 );
add( text );
}
@Override
protected void layout() {
super.layout();
bg.x = x;
bg.y = y;
bg.size( width, height );
close.setPos(
bg.x + bg.width() - bg.marginHor() / 2 - MARGIN_HOR - close.width(),
y + (height - close.height()) / 2 );
text.x = close.left() - MARGIN_HOR - text.width();
text.y = y + (height - text.height()) / 2;
PixelScene.align( text );
}
public void text( String txt ) {
text.text( txt );
text.measure();
}
protected void onClose() {};
}
@@ -0,0 +1,359 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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.watabou.noosa.Game;
import com.watabou.noosa.Gizmo;
import com.watabou.noosa.Image;
import com.watabou.noosa.ui.Button;
import com.watabou.noosa.ui.Component;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndCatalogus;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndHero;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndInfoCell;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndInfoItem;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndInfoMob;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndInfoPlant;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
public class Toolbar extends Component {
private Tool btnWait;
private Tool btnSearch;
private Tool btnInfo;
private Tool btnResume;
private Tool btnInventory;
private Tool btnQuick;
private PickedUpItem pickedUp;
private boolean lastEnabled = true;
public Toolbar() {
super();
height = btnInventory.height();
}
@Override
protected void createChildren() {
add( btnWait = new Tool( 0, 7, 20, 24 ) {
@Override
protected void onClick() {
Dungeon.hero.rest( false );
};
protected boolean onLongClick() {
Dungeon.hero.rest( true );
return true;
};
} );
add( btnSearch = new Tool( 20, 7, 20, 24 ) {
@Override
protected void onClick() {
Dungeon.hero.search( true );
}
} );
add( btnInfo = new Tool( 40, 7, 21, 24 ) {
@Override
protected void onClick() {
GameScene.selectCell( informer );
}
} );
add( btnResume = new Tool( 61, 7, 21, 24 ) {
@Override
protected void onClick() {
Dungeon.hero.resume();
}
} );
add( btnInventory = new Tool( 82, 7, 23, 24 ) {
private GoldIndicator gold;
@Override
protected void onClick() {
GameScene.show( new WndBag( Dungeon.hero.belongings.backpack, null, WndBag.Mode.ALL, null ) );
}
protected boolean onLongClick() {
GameScene.show( new WndCatalogus() );
return true;
};
@Override
protected void createChildren() {
super.createChildren();
gold = new GoldIndicator();
add( gold );
};
@Override
protected void layout() {
super.layout();
gold.fill( this );
};
} );
add( btnQuick = new QuickslotTool( 105, 7, 22, 24 ) );
add( pickedUp = new PickedUpItem() );
}
@Override
protected void layout() {
btnWait.setPos( x, y );
btnSearch.setPos( btnWait.right(), y );
btnInfo.setPos( btnSearch.right(), y );
btnResume.setPos( btnInfo.right(), y );
btnQuick.setPos( width - btnQuick.width(), y );
btnInventory.setPos( btnQuick.left() - btnInventory.width(), y );
}
@Override
public void update() {
super.update();
if (lastEnabled != Dungeon.hero.ready) {
lastEnabled = Dungeon.hero.ready;
for (Gizmo tool : members) {
if (tool instanceof Tool) {
((Tool)tool).enable( lastEnabled );
}
}
}
btnResume.visible = Dungeon.hero.lastAction != null;
if (!Dungeon.hero.isAlive()) {
btnInventory.enable( true );
}
}
public void pickup( Item item ) {
pickedUp.reset( item,
btnInventory.centerX(),
btnInventory.centerY() );
}
private static CellSelector.Listener informer = new CellSelector.Listener() {
@Override
public void onSelect( Integer cell ) {
if (cell == null) {
return;
}
if (cell < 0 || cell > Level.LENGTH || (!Dungeon.level.visited[cell] && !Dungeon.level.mapped[cell])) {
GameScene.show( new WndMessage( "You don't know what is there." ) ) ;
return;
}
if (!Dungeon.visible[cell]) {
GameScene.show( new WndInfoCell( cell ) );
return;
}
if (cell == Dungeon.hero.pos) {
GameScene.show( new WndHero() );
return;
}
Mob mob = (Mob)Actor.findChar( cell );
if (mob != null) {
GameScene.show( new WndInfoMob( mob ) );
return;
}
Heap heap = Dungeon.level.heaps.get( cell );
if (heap != null) {
if (heap.type == Heap.Type.FOR_SALE && heap.size() == 1 && heap.peek().price() > 0) {
GameScene.show( new WndTradeItem( heap, false ) );
} else {
GameScene.show( new WndInfoItem( heap ) );
}
return;
}
Plant plant = Dungeon.level.plants.get( cell );
if (plant != null) {
GameScene.show( new WndInfoPlant( plant ) );
return;
}
GameScene.show( new WndInfoCell( cell ) );
}
@Override
public String prompt() {
return "Select a cell to examine";
}
};
private static class Tool extends Button {
private static final int BGCOLOR = 0x7B8073;
private Image base;
public Tool( int x, int y, int width, int height ) {
super();
base.frame( x, y, width, height );
this.width = width;
this.height = height;
}
@Override
protected void createChildren() {
super.createChildren();
base = new Image( Assets.TOOLBAR );
add( base );
}
@Override
protected void layout() {
super.layout();
base.x = x;
base.y = y;
}
@Override
protected void onTouchDown() {
base.brightness( 1.4f );
}
@Override
protected void onTouchUp() {
if (active) {
base.resetColor();
} else {
base.tint( BGCOLOR, 0.7f );
}
}
public void enable( boolean value ) {
if (value != active) {
if (value) {
base.resetColor();
} else {
base.tint( BGCOLOR, 0.7f );
}
active = value;
}
}
}
private static class QuickslotTool extends Tool {
private QuickSlot slot;
public QuickslotTool( int x, int y, int width, int height ) {
super( x, y, width, height );
}
@Override
protected void createChildren() {
super.createChildren();
slot = new QuickSlot();
add( slot );
}
@Override
protected void layout() {
super.layout();
slot.setRect( x + 1, y + 2, width - 2, height - 2 );
}
@Override
public void enable( boolean value ) {
slot.enable( value );
active = value;
}
}
private static class PickedUpItem extends ItemSprite {
private static final float DISTANCE = DungeonTilemap.SIZE;
private static final float DURATION = 0.2f;
private float dstX;
private float dstY;
private float left;
public PickedUpItem() {
super();
originToCenter();
active =
visible =
false;
}
public void reset( Item item, float dstX, float dstY ) {
view( item.image(), item.glowing() );
active =
visible =
true;
this.dstX = dstX - ItemSprite.SIZE / 2;
this.dstY = dstY - ItemSprite.SIZE / 2;
left = DURATION;
x = this.dstX - DISTANCE;
y = this.dstY - DISTANCE;
alpha( 1 );
}
@Override
public void update() {
super.update();
if ((left -= Game.elapsed) <= 0) {
visible =
active =
false;
} else {
float p = left / DURATION;
scale.set( (float)Math.sqrt( p ) );
float offset = DISTANCE * p;
x = dstX - offset;
y = dstY - offset;
}
}
}
}
@@ -0,0 +1,199 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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 java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.watabou.input.Keys;
import com.watabou.input.Keys.Key;
import com.watabou.input.Touchscreen.Touch;
import com.watabou.noosa.Camera;
import com.watabou.noosa.Game;
import com.watabou.noosa.Group;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.TouchArea;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.watabou.utils.Signal;
public class Window extends Group implements Signal.Listener<Key> {
protected int width;
protected int height;
protected TouchArea blocker;
protected NinePatch chrome;
public static final int TITLE_COLOR = 0xFFFF44;
public Window() {
this( 0, 0, Chrome.get( Chrome.Type.WINDOW ) );
}
public Window( int width, int height ) {
this( width, height, Chrome.get( Chrome.Type.WINDOW ) );
}
public Window( int width, int height, NinePatch chrome ) {
super();
blocker = new TouchArea( 0, 0, PixelScene.uiCamera.width, PixelScene.uiCamera.height ) {
@Override
protected void onClick( Touch touch ) {
if (!Window.this.chrome.overlapsScreenPoint(
(int)touch.current.x,
(int)touch.current.y )) {
onBackPressed();
}
}
};
blocker.camera = PixelScene.uiCamera;
add( blocker );
this.chrome = chrome;
this.width = width;
this.height = height;
chrome.x = -chrome.marginLeft();
chrome.y = -chrome.marginTop();
chrome.size(
width - chrome.x + chrome.marginRight(),
height - chrome.y + chrome.marginBottom() );
add( chrome );
camera = new Camera( 0, 0,
(int)chrome.width,
(int)chrome.height,
PixelScene.defaultZoom );
camera.x = (int)(Game.width - camera.width * camera.zoom) / 2;
camera.y = (int)(Game.height - camera.height * camera.zoom) / 2;
camera.scroll.set( chrome.x, chrome.y );
Camera.add( camera );
Keys.event.add( this );
}
public void resize( int w, int h ) {
this.width = w;
this.height = h;
chrome.size(
width + chrome.marginHor(),
height + chrome.marginVer() );
camera.resize( (int)chrome.width, (int)chrome.height );
camera.x = (int)(Game.width - camera.screenWidth()) / 2;
camera.y = (int)(Game.height - camera.screenHeight()) / 2;
}
public void hide() {
parent.erase( this );
destroy();
}
@Override
public void destroy() {
super.destroy();
Camera.remove( camera );
Keys.event.remove( this );
}
@Override
public void onSignal( Key key ) {
if (key.pressed) {
switch (key.code) {
case Keys.BACK:
onBackPressed();
break;
case Keys.MENU:
onMenuPressed();
break;
}
}
Keys.event.cancel();
}
public void onBackPressed() {
hide();
}
public void onMenuPressed() {
}
protected static class Highlighter {
private static final Pattern HIGHLIGHTER = Pattern.compile( "_(.*?)_" );
private static final Pattern STRIPPER = Pattern.compile( "[ \n]" );
public String text;
public boolean[] mask;
public Highlighter( String text ) {
String stripped = STRIPPER.matcher( text ).replaceAll( "" );
mask = new boolean[stripped.length()];
Matcher m = HIGHLIGHTER.matcher( stripped );
int pos = 0;
int lastMatch = 0;
while (m.find()) {
pos += (m.start() - lastMatch);
int groupLen = m.group( 1 ).length();
for (int i=pos; i < pos + groupLen; i++) {
mask[i] = true;
}
pos += groupLen;
lastMatch = m.end();
}
m.reset( text );
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement( sb, m.group( 1 ) );
}
m.appendTail( sb );
this.text = sb.toString();
}
public boolean[] inverted() {
boolean[] result = new boolean[mask.length];
for (int i=0; i < result.length; i++) {
result[i] = !mask[i];
}
return result;
}
public boolean isHighlighted() {
for (int i=0; i < mask.length; i++) {
if (mask[i]) {
return true;
}
}
return false;
}
}
}