mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
wisp harvest and ScrollBarFrame
This commit is contained in:
parent
50164d8ef7
commit
84f015ef42
@ -160,6 +160,11 @@ public class CascDataSource implements DataSource {
|
||||
return internalGetFile(filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
private File internalGetFile(final String tempFilepath) {
|
||||
try {
|
||||
if (this.rootFileSystem.isFile(tempFilepath) && this.rootFileSystem.isFileAvailable(tempFilepath)) {
|
||||
|
@ -47,6 +47,24 @@ public class CompoundDataSource implements DataSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
try {
|
||||
for (int i = this.mpqList.size() - 1; i >= 0; i--) {
|
||||
final DataSource mpq = this.mpqList.get(i);
|
||||
final File tempProduct = mpq.getDirectory(filepath);
|
||||
if (tempProduct != null) {
|
||||
return tempProduct;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer read(final String path) throws IOException {
|
||||
try {
|
||||
|
@ -28,6 +28,15 @@ public interface DataSource {
|
||||
*/
|
||||
File getFile(String filepath) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns a directory from a FolderDataSource, otherwise returns null
|
||||
*
|
||||
* @param filepath
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
File getDirectory(String filepath) throws IOException;
|
||||
|
||||
ByteBuffer read(String path) throws IOException;
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,16 @@ public class FolderDataSource implements DataSource {
|
||||
return new File(this.folderPath.toString() + File.separatorChar + filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
filepath = fixFilepath(filepath);
|
||||
File file = new File(this.folderPath.toString() + File.separatorChar + filepath);
|
||||
if(!file.exists() || !file.isDirectory()) {
|
||||
return null;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer read(String path) throws IOException {
|
||||
path = fixFilepath(path);
|
||||
|
@ -112,6 +112,11 @@ public class MpqDataSource implements DataSource {
|
||||
return tempProduct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(final String filepath) {
|
||||
try {
|
||||
|
@ -22,6 +22,11 @@ public class SubdirDataSource implements DataSource {
|
||||
return this.dataSource.getFile(this.subdir + filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
return this.dataSource.getDirectory(this.subdir + filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer read(final String path) throws IOException {
|
||||
return this.dataSource.read(this.subdir + path);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@ public class GlueButtonFrame extends AbstractRenderableFrame implements Clickabl
|
||||
private UIFrame activeChild;
|
||||
|
||||
private Runnable onClick;
|
||||
private ButtonListener buttonListener = ButtonListener.DO_NOTHING;
|
||||
|
||||
public GlueButtonFrame(final String name, final UIFrame parent) {
|
||||
super(name, parent);
|
||||
@ -66,6 +67,10 @@ public class GlueButtonFrame extends AbstractRenderableFrame implements Clickabl
|
||||
this.onClick = onClick;
|
||||
}
|
||||
|
||||
public void setButtonListener(ButtonListener buttonListener) {
|
||||
this.buttonListener = buttonListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) {
|
||||
if (this.controlBackdrop != null) {
|
||||
@ -101,14 +106,20 @@ public class GlueButtonFrame extends AbstractRenderableFrame implements Clickabl
|
||||
@Override
|
||||
public void mouseDown(final GameUI gameUI, final Viewport uiViewport) {
|
||||
if (this.enabled) {
|
||||
this.activeChild = this.controlPushedBackdrop;
|
||||
if(this.controlPushedBackdrop != null) {
|
||||
this.activeChild = this.controlPushedBackdrop;
|
||||
}
|
||||
buttonListener.mouseDown(gameUI, uiViewport);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(final GameUI gameUI, final Viewport uiViewport) {
|
||||
if (this.enabled) {
|
||||
this.activeChild = this.controlBackdrop;
|
||||
if(this.controlBackdrop != null) {
|
||||
this.activeChild = this.controlBackdrop;
|
||||
}
|
||||
buttonListener.mouseUp(gameUI, uiViewport);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +150,11 @@ public class GlueButtonFrame extends AbstractRenderableFrame implements Clickabl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
buttonListener.mouseDragged(rootFrame, uiViewport, x,y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) {
|
||||
@ -163,4 +179,21 @@ public class GlueButtonFrame extends AbstractRenderableFrame implements Clickabl
|
||||
return super.getFrameChildUnderMouse(screenX, screenY);
|
||||
}
|
||||
|
||||
public interface ButtonListener {
|
||||
void mouseDown(GameUI gameUI, Viewport uiViewport);
|
||||
void mouseUp(GameUI gameUI, Viewport uiViewport);
|
||||
void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y);
|
||||
|
||||
ButtonListener DO_NOTHING = new ButtonListener() {
|
||||
@Override
|
||||
public void mouseDown(GameUI gameUI, Viewport uiViewport) {}
|
||||
|
||||
@Override
|
||||
public void mouseUp(GameUI gameUI, Viewport uiViewport) {}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,188 +15,281 @@ import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify;
|
||||
|
||||
public class ListBoxFrame extends ControlFrame {
|
||||
// TODO where are these colors in the UI definition files?
|
||||
private static final Color SELECT_COLOR = Color.BLUE;
|
||||
private static final Color MOUSE_OVER_HIGHLIGHT_COLOR = new Color(0.3f, 0.3f, 1.0f, 0.25f);
|
||||
public class ListBoxFrame extends ControlFrame implements ScrollBarFrame.ScrollBarChangeListener {
|
||||
// TODO where are these colors in the UI definition files?
|
||||
private static final Color SELECT_COLOR = Color.BLUE;
|
||||
private static final Color MOUSE_OVER_HIGHLIGHT_COLOR = new Color(0.3f, 0.3f, 1.0f, 0.25f);
|
||||
|
||||
private final List<String> listItems = new ArrayList<>();
|
||||
private final List<SingleStringFrame> stringFrames = new ArrayList<>();
|
||||
private BitmapFont frameFont;
|
||||
private float listBoxBorder;
|
||||
private int selectedIndex = -1;
|
||||
private int mouseOverIndex = -1;
|
||||
private final List<String> listItems = new ArrayList<>();
|
||||
private final List<SingleStringFrame> stringFrames = new ArrayList<>();
|
||||
private BitmapFont frameFont;
|
||||
private float listBoxBorder;
|
||||
private int selectedIndex = -1;
|
||||
private int mouseOverIndex = -1;
|
||||
|
||||
private final TextureFrame selectionFrame;
|
||||
private final TextureFrame mouseHighlightFrame;
|
||||
private GameUI gameUI;
|
||||
private Viewport viewport;
|
||||
private Runnable onSelect;
|
||||
private final TextureFrame selectionFrame;
|
||||
private final TextureFrame mouseHighlightFrame;
|
||||
private GameUI gameUI;
|
||||
private Viewport viewport;
|
||||
private Runnable onSelect;
|
||||
private ScrollBarFrame scrollBarFrame;
|
||||
|
||||
public ListBoxFrame(final String name, final UIFrame parent, final Viewport viewport) {
|
||||
super(name, parent);
|
||||
this.listBoxBorder = GameUI.convertX(viewport, 0.01f);
|
||||
this.selectionFrame = new TextureFrame(null, this, false, null);
|
||||
this.mouseHighlightFrame = new TextureFrame(null, this, false, null);
|
||||
final Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888);
|
||||
pixmap.setColor(SELECT_COLOR);
|
||||
pixmap.fill();
|
||||
this.selectionFrame.setTexture(new Texture(pixmap));
|
||||
final Pixmap mousePixmap = new Pixmap(1, 1, Format.RGBA8888);
|
||||
mousePixmap.setColor(MOUSE_OVER_HIGHLIGHT_COLOR);
|
||||
mousePixmap.fill();
|
||||
this.mouseHighlightFrame.setTexture(new Texture(mousePixmap));
|
||||
}
|
||||
public ListBoxFrame(final String name, final UIFrame parent, final Viewport viewport) {
|
||||
super(name, parent);
|
||||
this.listBoxBorder = GameUI.convertX(viewport, 0.01f);
|
||||
this.selectionFrame = new TextureFrame(null, this, false, null);
|
||||
this.mouseHighlightFrame = new TextureFrame(null, this, false, null);
|
||||
final Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888);
|
||||
pixmap.setColor(SELECT_COLOR);
|
||||
pixmap.fill();
|
||||
this.selectionFrame.setTexture(new Texture(pixmap));
|
||||
final Pixmap mousePixmap = new Pixmap(1, 1, Format.RGBA8888);
|
||||
mousePixmap.setColor(MOUSE_OVER_HIGHLIGHT_COLOR);
|
||||
mousePixmap.fill();
|
||||
this.mouseHighlightFrame.setTexture(new Texture(mousePixmap));
|
||||
}
|
||||
|
||||
public void setListBoxBorder(final float listBoxBorder) {
|
||||
this.listBoxBorder = listBoxBorder;
|
||||
}
|
||||
public void setScrollBarFrame(ScrollBarFrame scrollBarFrame) {
|
||||
this.scrollBarFrame = scrollBarFrame;
|
||||
// TODO might be a better place to add these set points, but we definitely need them
|
||||
scrollBarFrame.addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this, FramePoint.TOPRIGHT, -listBoxBorder, -listBoxBorder));
|
||||
scrollBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, this, FramePoint.BOTTOMRIGHT, -listBoxBorder, listBoxBorder));
|
||||
scrollBarFrame.setChangeListener(this);
|
||||
}
|
||||
|
||||
public float getListBoxBorder() {
|
||||
return this.listBoxBorder;
|
||||
}
|
||||
public ScrollBarFrame getScrollBarFrame() {
|
||||
return scrollBarFrame;
|
||||
}
|
||||
|
||||
public void setFrameFont(final BitmapFont frameFont) {
|
||||
this.frameFont = frameFont;
|
||||
}
|
||||
public void setListBoxBorder(final float listBoxBorder) {
|
||||
this.listBoxBorder = listBoxBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) {
|
||||
this.gameUI = gameUI;
|
||||
this.viewport = viewport;
|
||||
super.innerPositionBounds(gameUI, viewport);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
public float getListBoxBorder() {
|
||||
return this.listBoxBorder;
|
||||
}
|
||||
|
||||
private void positionChildren(final GameUI gameUI, final Viewport viewport) {
|
||||
for (final SingleStringFrame frame : this.stringFrames) {
|
||||
frame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
this.selectionFrame.positionBounds(gameUI, viewport);
|
||||
this.mouseHighlightFrame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
public void setFrameFont(final BitmapFont frameFont) {
|
||||
this.frameFont = frameFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) {
|
||||
super.internalRender(batch, baseFont, glyphLayout);
|
||||
this.selectionFrame.render(batch, baseFont, glyphLayout);
|
||||
this.mouseHighlightFrame.render(batch, baseFont, glyphLayout);
|
||||
for (final SingleStringFrame frame : this.stringFrames) {
|
||||
frame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) {
|
||||
this.gameUI = gameUI;
|
||||
this.viewport = viewport;
|
||||
super.innerPositionBounds(gameUI, viewport);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
|
||||
public void addItem(final String item, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.add(item);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
private void positionChildren(final GameUI gameUI, final Viewport viewport) {
|
||||
for (final SingleStringFrame frame : this.stringFrames) {
|
||||
frame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
this.selectionFrame.positionBounds(gameUI, viewport);
|
||||
this.mouseHighlightFrame.positionBounds(gameUI, viewport);
|
||||
if (scrollBarFrame != null) {
|
||||
this.scrollBarFrame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
}
|
||||
|
||||
public void setItems(final List<String> items, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.clear();
|
||||
this.listItems.addAll(items);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
@Override
|
||||
protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) {
|
||||
super.internalRender(batch, baseFont, glyphLayout);
|
||||
this.selectionFrame.render(batch, baseFont, glyphLayout);
|
||||
this.mouseHighlightFrame.render(batch, baseFont, glyphLayout);
|
||||
for (final SingleStringFrame frame : this.stringFrames) {
|
||||
frame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
if (scrollBarFrame != null) {
|
||||
scrollBarFrame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(final String item, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.remove(item);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
public void addItem(final String item, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.add(item);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
|
||||
public void removeItem(final int index, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.remove(index);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
public void setItems(final List<String> items, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.clear();
|
||||
this.listItems.addAll(items);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
|
||||
public void setSelectedIndex(final int selectedIndex) {
|
||||
this.selectedIndex = selectedIndex;
|
||||
}
|
||||
public void removeItem(final String item, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.remove(item);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return this.selectedIndex;
|
||||
}
|
||||
public void removeItem(final int index, final GameUI gameUI, final Viewport viewport) {
|
||||
this.listItems.remove(index);
|
||||
updateUI(gameUI, viewport);
|
||||
}
|
||||
|
||||
private void updateUI(final GameUI gameUI, final Viewport viewport) {
|
||||
this.stringFrames.clear();
|
||||
SingleStringFrame prev = null;
|
||||
int i = 0;
|
||||
boolean foundSelected = false;
|
||||
boolean foundMouseOver = false;
|
||||
for (final String string : this.listItems) {
|
||||
final boolean selected = (i == this.selectedIndex);
|
||||
final boolean mousedOver = (i == this.mouseOverIndex);
|
||||
final SingleStringFrame stringFrame = new SingleStringFrame("LISTY" + i++, this, Color.WHITE,
|
||||
TextJustify.LEFT, TextJustify.MIDDLE, this.frameFont);
|
||||
stringFrame.setText(string);
|
||||
stringFrame.setWidth(this.renderBounds.width - (this.listBoxBorder * 2));
|
||||
stringFrame.setHeight(this.frameFont.getLineHeight());
|
||||
if (prev != null) {
|
||||
stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, prev, FramePoint.BOTTOMLEFT, 0, 0));
|
||||
}
|
||||
else {
|
||||
stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, this.listBoxBorder,
|
||||
-this.listBoxBorder));
|
||||
}
|
||||
this.stringFrames.add(stringFrame);
|
||||
prev = stringFrame;
|
||||
if (selected) {
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundSelected = true;
|
||||
}
|
||||
else if (mousedOver) {
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundMouseOver = true;
|
||||
}
|
||||
}
|
||||
this.selectionFrame.setVisible(foundSelected);
|
||||
this.mouseHighlightFrame.setVisible(foundMouseOver);
|
||||
positionChildren(gameUI, viewport);
|
||||
}
|
||||
public void setSelectedIndex(final int selectedIndex) {
|
||||
this.selectedIndex = selectedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
int index = 0;
|
||||
for (final SingleStringFrame stringFrame : this.stringFrames) {
|
||||
if (stringFrame.getRenderBounds().contains(screenX, screenY)) {
|
||||
this.selectedIndex = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
updateUI(this.gameUI, this.viewport);
|
||||
if (this.onSelect != null) {
|
||||
this.onSelect.run();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
public int getSelectedIndex() {
|
||||
return this.selectedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
int index = 0;
|
||||
int mouseOverIndex = -1;
|
||||
for (final SingleStringFrame stringFrame : this.stringFrames) {
|
||||
if (stringFrame.getRenderBounds().contains(screenX, screenY)) {
|
||||
mouseOverIndex = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (this.mouseOverIndex != mouseOverIndex) {
|
||||
this.mouseOverIndex = mouseOverIndex;
|
||||
updateUI(this.gameUI, this.viewport);
|
||||
}
|
||||
}
|
||||
return super.getFrameChildUnderMouse(screenX, screenY);
|
||||
}
|
||||
public String getSelectedItem() {
|
||||
if(selectedIndex < 0 || selectedIndex >= listItems.size()) {
|
||||
return null;
|
||||
}
|
||||
return listItems.get(selectedIndex);
|
||||
}
|
||||
|
||||
public void setOnSelect(final Runnable onSelect) {
|
||||
this.onSelect = onSelect;
|
||||
}
|
||||
private void updateUI(final GameUI gameUI, final Viewport viewport) {
|
||||
SingleStringFrame prev = null;
|
||||
boolean foundSelected = false;
|
||||
boolean foundMouseOver = false;
|
||||
int numStringFrames = (int)(Math.floor( (renderBounds.height - listBoxBorder*2) / (frameFont.getLineHeight()) ));
|
||||
int scrollOffset = computeScrollOffset(numStringFrames);
|
||||
if(numStringFrames != stringFrames.size()) {
|
||||
this.stringFrames.clear();
|
||||
for(int stringFrameIndex = 0; stringFrameIndex < numStringFrames; stringFrameIndex++) {
|
||||
final int index = stringFrameIndex + scrollOffset;
|
||||
final boolean selected = (index == this.selectedIndex);
|
||||
final boolean mousedOver = (index == this.mouseOverIndex);
|
||||
final SingleStringFrame stringFrame = new SingleStringFrame("LISTY" + index, this, Color.WHITE,
|
||||
TextJustify.LEFT, TextJustify.MIDDLE, this.frameFont);
|
||||
if(index < listItems.size()) {
|
||||
stringFrame.setText(listItems.get(index));
|
||||
}
|
||||
stringFrame.setWidth(this.renderBounds.width - (this.listBoxBorder * 2));
|
||||
stringFrame.setHeight(this.frameFont.getLineHeight());
|
||||
if (prev != null) {
|
||||
stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, prev, FramePoint.BOTTOMLEFT, 0, 0));
|
||||
} else {
|
||||
stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, this.listBoxBorder,
|
||||
-this.listBoxBorder));
|
||||
}
|
||||
this.stringFrames.add(stringFrame);
|
||||
prev = stringFrame;
|
||||
if (selected) {
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundSelected = true;
|
||||
} else if (mousedOver) {
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundMouseOver = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int stringFrameIndex = 0; stringFrameIndex < numStringFrames; stringFrameIndex++) {
|
||||
final int index = stringFrameIndex + scrollOffset;
|
||||
final boolean selected = (index == this.selectedIndex);
|
||||
final boolean mousedOver = (index == this.mouseOverIndex);
|
||||
SingleStringFrame stringFrame = stringFrames.get(stringFrameIndex);
|
||||
if(index < listItems.size()) {
|
||||
stringFrame.setText(listItems.get(index));
|
||||
}
|
||||
if (selected) {
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.selectionFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundSelected = true;
|
||||
} else if (mousedOver) {
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0));
|
||||
this.mouseHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0));
|
||||
foundMouseOver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.selectionFrame.setVisible(foundSelected);
|
||||
this.mouseHighlightFrame.setVisible(foundMouseOver);
|
||||
positionChildren(gameUI, viewport);
|
||||
}
|
||||
|
||||
private int computeScrollOffset(int numStringFrames) {
|
||||
int scrollOffset;
|
||||
if(scrollBarFrame != null && listItems.size() > numStringFrames){
|
||||
scrollOffset = (int)Math.ceil(((100 - scrollBarFrame.getValue()) / 100f) * (listItems.size() - numStringFrames));
|
||||
} else {
|
||||
scrollOffset = 0;
|
||||
}
|
||||
return scrollOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
if(scrollBarFrame!=null) {
|
||||
UIFrame sliderFrameChildUnderMouse = scrollBarFrame.touchDown(screenX, screenY, button);
|
||||
if (sliderFrameChildUnderMouse != null) {
|
||||
return sliderFrameChildUnderMouse;
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
for (final SingleStringFrame stringFrame : this.stringFrames) {
|
||||
if (stringFrame.getRenderBounds().contains(screenX, screenY)) {
|
||||
this.selectedIndex = index + computeScrollOffset(stringFrames.size());
|
||||
}
|
||||
index++;
|
||||
}
|
||||
updateUI(this.gameUI, this.viewport);
|
||||
if (this.onSelect != null) {
|
||||
this.onSelect.run();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(float screenX, float screenY, int button) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
if (scrollBarFrame != null) {
|
||||
UIFrame sliderFrameChildUnderMouse = scrollBarFrame.touchDown(screenX, screenY, button);
|
||||
if (sliderFrameChildUnderMouse != null) {
|
||||
return sliderFrameChildUnderMouse;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.touchUp(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
if(scrollBarFrame!=null) {
|
||||
UIFrame sliderFrameChildUnderMouse = scrollBarFrame.getFrameChildUnderMouse(screenX, screenY);
|
||||
if (sliderFrameChildUnderMouse != null) {
|
||||
return sliderFrameChildUnderMouse;
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
int mouseOverIndex = -1;
|
||||
for (final SingleStringFrame stringFrame : this.stringFrames) {
|
||||
if (stringFrame.getRenderBounds().contains(screenX, screenY)) {
|
||||
mouseOverIndex = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (this.mouseOverIndex != mouseOverIndex) {
|
||||
this.mouseOverIndex = mouseOverIndex + computeScrollOffset(stringFrames.size());
|
||||
updateUI(this.gameUI, this.viewport);
|
||||
}
|
||||
}
|
||||
return super.getFrameChildUnderMouse(screenX, screenY);
|
||||
}
|
||||
|
||||
public void setOnSelect(final Runnable onSelect) {
|
||||
this.onSelect = onSelect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(GameUI gameUI, Viewport uiViewport, int newValue) {
|
||||
updateUI(gameUI, uiViewport);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,261 @@
|
||||
package com.etheller.warsmash.parsers.fdf.frames;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame;
|
||||
|
||||
public class ScrollBarFrame extends AbstractRenderableFrame implements ClickableFrame {
|
||||
private UIFrame controlBackdrop;
|
||||
private UIFrame incButtonFrame;
|
||||
private UIFrame decButtonFrame;
|
||||
private UIFrame thumbButtonFrame;
|
||||
private int scrollValuePercent = 50;
|
||||
private ScrollBarChangeListener changeListener = ScrollBarChangeListener.DO_NOTHING;
|
||||
|
||||
public ScrollBarFrame(final String name, final UIFrame parent, boolean vertical) {
|
||||
super(name, parent);
|
||||
}
|
||||
|
||||
public void setControlBackdrop(final UIFrame controlBackdrop) {
|
||||
this.controlBackdrop = controlBackdrop;
|
||||
}
|
||||
|
||||
public void setIncButtonFrame(UIFrame incButtonFrame) {
|
||||
this.incButtonFrame = incButtonFrame;
|
||||
((GlueButtonFrame)incButtonFrame).setButtonListener(new GlueButtonFrame.ButtonListener() {
|
||||
@Override
|
||||
public void mouseDown(GameUI gameUI, Viewport uiViewport) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(GameUI gameUI, Viewport uiViewport) {
|
||||
setValue(gameUI, uiViewport, scrollValuePercent+10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDecButtonFrame(UIFrame decButtonFrame) {
|
||||
this.decButtonFrame = decButtonFrame;
|
||||
((GlueButtonFrame)decButtonFrame).setButtonListener(new GlueButtonFrame.ButtonListener() {
|
||||
@Override
|
||||
public void mouseDown(GameUI gameUI, Viewport uiViewport) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(GameUI gameUI, Viewport uiViewport) {
|
||||
setValue(gameUI, uiViewport, scrollValuePercent-10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setThumbButtonFrame(UIFrame thumbButtonFrame) {
|
||||
if (this.thumbButtonFrame instanceof GlueButtonFrame) {
|
||||
((GlueButtonFrame) this.thumbButtonFrame).setButtonListener(GlueButtonFrame.ButtonListener.DO_NOTHING);
|
||||
}
|
||||
this.thumbButtonFrame = thumbButtonFrame;
|
||||
if (thumbButtonFrame instanceof GlueButtonFrame) {
|
||||
GlueButtonFrame frame = (GlueButtonFrame) thumbButtonFrame;
|
||||
frame.setButtonListener(new GlueButtonFrame.ButtonListener() {
|
||||
@Override
|
||||
public void mouseDown(GameUI gameUI, Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(GameUI gameUI, Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
ScrollBarFrame.this.mouseDragged(rootFrame, uiViewport, x, y);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private float getMaxThumbButtonTravelDistance() {
|
||||
return renderBounds.height - thumbButtonFrame.getAssignedHeight() - incButtonFrame.getAssignedHeight() - decButtonFrame.getAssignedHeight();
|
||||
}
|
||||
|
||||
public void setValue(GameUI gameUI, Viewport uiViewport, int percent) {
|
||||
this.scrollValuePercent = Math.min(100,Math.max(0,percent));
|
||||
updateThumbButtonPoint();
|
||||
changeListener.onChange(gameUI, uiViewport, this.scrollValuePercent);
|
||||
positionBounds(gameUI, uiViewport);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return scrollValuePercent;
|
||||
}
|
||||
|
||||
public void updateThumbButtonPoint() {
|
||||
float newYValue = scrollValuePercent / 100f * getMaxThumbButtonTravelDistance();
|
||||
thumbButtonFrame.addSetPoint(new SetPoint(FramePoint.BOTTOM, decButtonFrame, FramePoint.TOP, 0, newYValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) {
|
||||
if (this.controlBackdrop != null) {
|
||||
this.controlBackdrop.positionBounds(gameUI, viewport);
|
||||
}
|
||||
if (this.incButtonFrame != null) {
|
||||
this.incButtonFrame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
if (this.decButtonFrame != null) {
|
||||
this.decButtonFrame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
updateThumbButtonPoint();
|
||||
if (this.thumbButtonFrame != null) {
|
||||
this.thumbButtonFrame.positionBounds(gameUI, viewport);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) {
|
||||
if (this.controlBackdrop != null) {
|
||||
controlBackdrop.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
if (this.incButtonFrame != null) {
|
||||
this.incButtonFrame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
if (this.decButtonFrame != null) {
|
||||
this.decButtonFrame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
if (this.thumbButtonFrame != null) {
|
||||
this.thumbButtonFrame.render(batch, baseFont, glyphLayout);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDown(final GameUI gameUI, final Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(final GameUI gameUI, final Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExit(final GameUI gameUI, final Viewport uiViewport) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final int button) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
float maxThumbButtonTravelDistance = getMaxThumbButtonTravelDistance();
|
||||
int newScrollValuePercent = Math.min(100,Math.max(0,(int)((y - renderBounds.y - decButtonFrame.getAssignedHeight() - thumbButtonFrame.getAssignedHeight()/2) / maxThumbButtonTravelDistance * 100)));
|
||||
if(newScrollValuePercent != scrollValuePercent) {
|
||||
setValue(rootFrame, uiViewport, newScrollValuePercent);
|
||||
positionBounds(rootFrame, uiViewport);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
UIFrame frameChildUnderMouse = thumbButtonFrame.touchUp(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = incButtonFrame.touchUp(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = decButtonFrame.touchUp(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = controlBackdrop.touchUp(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return super.touchUp(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
UIFrame frameChildUnderMouse = thumbButtonFrame.touchDown(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = incButtonFrame.touchDown(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = decButtonFrame.touchDown(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = controlBackdrop.touchDown(screenX, screenY, button);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
UIFrame frameChildUnderMouse = thumbButtonFrame.getFrameChildUnderMouse(screenX, screenY);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = incButtonFrame.getFrameChildUnderMouse(screenX, screenY);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = decButtonFrame.getFrameChildUnderMouse(screenX, screenY);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
frameChildUnderMouse = controlBackdrop.getFrameChildUnderMouse(screenX, screenY);
|
||||
if (frameChildUnderMouse != null) {
|
||||
return frameChildUnderMouse;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return super.getFrameChildUnderMouse(screenX, screenY);
|
||||
}
|
||||
|
||||
public void setChangeListener(ScrollBarChangeListener changeListener) {
|
||||
this.changeListener = changeListener;
|
||||
}
|
||||
|
||||
public interface ScrollBarChangeListener {
|
||||
void onChange(GameUI gameUI, Viewport uiViewport, int newValue);
|
||||
|
||||
ScrollBarChangeListener DO_NOTHING = new ScrollBarChangeListener() {
|
||||
@Override
|
||||
public void onChange(GameUI gameUI, Viewport uiViewport, int newValue) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -170,6 +170,11 @@ public class SimpleButtonFrame extends AbstractRenderableFrame implements Clicka
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) {
|
||||
|
@ -144,6 +144,11 @@ public class War3Map implements DataSource {
|
||||
return this.dataSource.getFile(filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory(String filepath) throws IOException {
|
||||
return this.dataSource.getDirectory(filepath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(final String filepath) {
|
||||
return this.dataSource.has(filepath);
|
||||
|
@ -536,8 +536,10 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
}
|
||||
final MdxModel model = (MdxModel) this.model;
|
||||
|
||||
for (final GenericGroup group : model.opaqueGroups) {
|
||||
group.render(this, this.scene.camera.viewProjectionMatrix);
|
||||
if(additiveOverrideMeshMode) {
|
||||
for (final GenericGroup group : model.opaqueGroups) {
|
||||
group.render(this, this.scene.camera.viewProjectionMatrix);
|
||||
}
|
||||
}
|
||||
for (final GenericGroup group : model.translucentGroups) {
|
||||
group.render(this, this.scene.camera.viewProjectionMatrix);
|
||||
|
@ -21,6 +21,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderComponent;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
|
||||
|
||||
@ -836,6 +837,34 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
spawnEffectOnUnit(unit, abilityUI.getTargetArt(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimulationRenderComponent createSpellEffectOverDestructable(CUnit source, CDestructable target, War3ID alias, float artAttachmentHeight) {
|
||||
final AbilityUI abilityUI = War3MapViewer.this.abilityDataUI.getUI(alias);
|
||||
String effectPath = abilityUI.getTargetArt(0);
|
||||
RenderDestructable renderDestructable = War3MapViewer.this.destructableToRenderPeer.get(target);
|
||||
final MdxModel spawnedEffectModel = loadModelMdx(effectPath);
|
||||
if (spawnedEffectModel != null) {
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) spawnedEffectModel
|
||||
.addInstance();
|
||||
modelInstance.setTeamColor(simulation.getPlayer(source.getPlayerIndex()).getColor());
|
||||
modelInstance.setLocation(renderDestructable.getX(), renderDestructable.getY(), renderDestructable.getZ() + artAttachmentHeight);
|
||||
modelInstance.setScene(War3MapViewer.this.worldScene);
|
||||
final RenderSpellEffect renderAttackInstant = new RenderSpellEffect(modelInstance,
|
||||
War3MapViewer.this,
|
||||
0,
|
||||
RenderSpellEffect.STAND_ONLY);
|
||||
renderAttackInstant.setAnimations(RenderSpellEffect.STAND_ONLY, false);
|
||||
War3MapViewer.this.projectiles.add(renderAttackInstant);
|
||||
return new SimulationRenderComponent() {
|
||||
@Override
|
||||
public void remove() {
|
||||
renderAttackInstant.setAnimations(RenderSpellEffect.DEATH_ONLY, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnUnitReadySound(final CUnit trainedUnit) {
|
||||
final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(trainedUnit);
|
||||
@ -898,6 +927,28 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loopAbilitySoundEffect(CUnit caster, War3ID alias) {
|
||||
final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(caster);
|
||||
final AbilityUI abilityUi = War3MapViewer.this.abilityDataUI.getUI(alias);
|
||||
if (abilityUi.getEffectSoundLooped() != null) {
|
||||
War3MapViewer.this.uiSounds.getSound(abilityUi.getEffectSoundLooped()).play(
|
||||
War3MapViewer.this.worldScene.audioContext, renderPeer.getX(), renderPeer.getY(),
|
||||
renderPeer.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopAbilitySoundEffect(CUnit caster, War3ID alias) {
|
||||
final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(caster);
|
||||
final AbilityUI abilityUi = War3MapViewer.this.abilityDataUI.getUI(alias);
|
||||
if (abilityUi.getEffectSoundLooped() != null) {
|
||||
// TODO below this probably stops all instances of the sound, which is silly
|
||||
// and busted. Would be better to keep a notion of sound instance
|
||||
War3MapViewer.this.uiSounds.getSound(abilityUi.getEffectSoundLooped()).stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unitPreferredSelectionReplacement(final CUnit oldUnit, final CUnit newUnit) {
|
||||
final RenderUnit oldRenderPeer = War3MapViewer.this.unitToRenderPeer.get(oldUnit);
|
||||
|
@ -13,10 +13,13 @@ import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||
|
||||
public class RenderSpellEffect implements RenderEffect {
|
||||
public static final PrimaryTag[] DEFAULT_ANIMATION_QUEUE = { PrimaryTag.BIRTH, PrimaryTag.STAND, PrimaryTag.DEATH };
|
||||
public static final PrimaryTag[] STAND_ONLY = { PrimaryTag.STAND };
|
||||
public static final PrimaryTag[] DEATH_ONLY = { PrimaryTag.DEATH };
|
||||
private final MdxComplexInstance modelInstance;
|
||||
private final PrimaryTag[] animationQueue;
|
||||
private PrimaryTag[] animationQueue;
|
||||
private int animationQueueIndex;
|
||||
private final List<Sequence> sequences;
|
||||
private boolean killWhenDone = true;
|
||||
|
||||
public RenderSpellEffect(final MdxComplexInstance modelInstance, final War3MapViewer war3MapViewer, final float yaw,
|
||||
final PrimaryTag[] animationQueue) {
|
||||
@ -33,11 +36,17 @@ public class RenderSpellEffect implements RenderEffect {
|
||||
@Override
|
||||
public boolean updateAnimations(final War3MapViewer war3MapViewer, final float deltaTime) {
|
||||
playNextAnimation();
|
||||
final boolean everythingDone = this.animationQueueIndex >= this.animationQueue.length;
|
||||
if (everythingDone) {
|
||||
war3MapViewer.worldScene.removeInstance(this.modelInstance);
|
||||
if(killWhenDone) {
|
||||
final boolean everythingDone = this.animationQueueIndex >= this.animationQueue.length;
|
||||
if (everythingDone) {
|
||||
war3MapViewer.worldScene.removeInstance(this.modelInstance);
|
||||
}
|
||||
return everythingDone;
|
||||
} else {
|
||||
animationQueueIndex = 0;
|
||||
playNextAnimation();;
|
||||
return false;
|
||||
}
|
||||
return everythingDone;
|
||||
}
|
||||
|
||||
private void playNextAnimation() {
|
||||
@ -50,4 +59,10 @@ public class RenderSpellEffect implements RenderEffect {
|
||||
this.animationQueueIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAnimations(PrimaryTag[] animations, boolean killWhenDone) {
|
||||
animationQueue = animations;
|
||||
animationQueueIndex = 0;
|
||||
this.killWhenDone = killWhenDone;
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.etheller.interpreter.ast.scope.GlobalScope;
|
||||
@ -49,6 +42,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimer;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderComponent;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||
|
||||
@ -87,6 +81,7 @@ public class CSimulation implements CPlayerAPI {
|
||||
private final List<TimeOfDayVariableEvent> timeOfDayVariableEvents = new ArrayList<>();
|
||||
private boolean timeOfDaySuspended;
|
||||
private boolean daytime;
|
||||
private Set<CDestructable> ownedTreeSet = new HashSet<>();
|
||||
|
||||
public CSimulation(final War3MapConfig config, final DataTable miscData, final MutableObjectData parsedUnitData,
|
||||
final MutableObjectData parsedItemData, final MutableObjectData parsedDestructableData,
|
||||
@ -121,7 +116,7 @@ public class CSimulation implements CPlayerAPI {
|
||||
for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) {
|
||||
final CBasePlayer configPlayer = config.getPlayer(i);
|
||||
final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex());
|
||||
final CRace defaultRace = CRace.NIGHTELF;
|
||||
final CRace defaultRace = CRace.ORC;
|
||||
final CPlayer newPlayer = new CPlayer(defaultRace, new float[] { startLoc.getX(), startLoc.getY() },
|
||||
configPlayer);
|
||||
if (WarsmashConstants.LOCAL_TEMP_TEST_ALL_PLAYERS_PLAYING) {
|
||||
@ -524,6 +519,14 @@ public class CSimulation implements CPlayerAPI {
|
||||
this.simulationRenderController.spawnAbilitySoundEffect(caster, alias);
|
||||
}
|
||||
|
||||
public void unitLoopSoundEffectEvent(final CUnit caster, final War3ID alias) {
|
||||
this.simulationRenderController.loopAbilitySoundEffect(caster, alias);
|
||||
}
|
||||
|
||||
public void unitStopSoundEffectEvent(final CUnit caster, final War3ID alias) {
|
||||
this.simulationRenderController.stopAbilitySoundEffect(caster, alias);
|
||||
}
|
||||
|
||||
public void unitPreferredSelectionReplacement(final CUnit unit, final CUnit newUnit) {
|
||||
this.simulationRenderController.unitPreferredSelectionReplacement(unit, newUnit);
|
||||
}
|
||||
@ -564,6 +567,22 @@ public class CSimulation implements CPlayerAPI {
|
||||
cItem.setLife(this, 0);
|
||||
}
|
||||
|
||||
public SimulationRenderComponent createSpellEffectOverDestructable(CUnit source, CDestructable target, War3ID alias, float artAttachmentHeight) {
|
||||
return simulationRenderController.createSpellEffectOverDestructable(source, target, alias, artAttachmentHeight);
|
||||
}
|
||||
|
||||
public void tagTreeOwned(CDestructable target) {
|
||||
ownedTreeSet.add(target);
|
||||
}
|
||||
|
||||
public void untagTreeOwned(CDestructable target) {
|
||||
ownedTreeSet.remove(target);
|
||||
}
|
||||
|
||||
public boolean isTreeOwned(CDestructable tree) {
|
||||
return ownedTreeSet.contains(tree);
|
||||
}
|
||||
|
||||
private static final class TimeOfDayVariableEvent extends VariableEvent {
|
||||
private final GlobalScope globalScope;
|
||||
|
||||
|
@ -0,0 +1,155 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest;
|
||||
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.util.WarsmashConstants;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconActiveAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorWispHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class CAbilityWispHarvest extends AbstractGenericSingleIconActiveAbility {
|
||||
public static final EnumSet<CTargetType> TREE_ALIVE_TYPE_ONLY = EnumSet.of(CTargetType.TREE, CTargetType.ALIVE);
|
||||
|
||||
private int lumberPerInterval;
|
||||
private float artAttachmentHeight;
|
||||
private float castRange;
|
||||
private float periodicIntervalLength;
|
||||
private int periodicIntervalLengthTicks;
|
||||
private CBehaviorWispHarvest behaviorWispHarvest;
|
||||
|
||||
|
||||
public CAbilityWispHarvest(final int handleId, final War3ID alias, final int lumberPerInterval, float artAttachmentHeight,
|
||||
float castRange, final float periodicIntervalLength) {
|
||||
super(handleId, alias);
|
||||
this.lumberPerInterval = lumberPerInterval;
|
||||
this.artAttachmentHeight = artAttachmentHeight;
|
||||
this.castRange = castRange;
|
||||
this.periodicIntervalLength = periodicIntervalLength;
|
||||
this.periodicIntervalLengthTicks = (int)(periodicIntervalLength / WarsmashConstants.SIMULATION_STEP_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||
this.behaviorWispHarvest = new CBehaviorWispHarvest(unit, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(final CSimulation game, final CUnit unit) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||
return this.behaviorWispHarvest.reset(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
|
||||
final AbilityPointTarget point) {
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return isToggleOn() ? OrderIds.returnresources : OrderIds.wispharvest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToggleOn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityActivationReceiver receiver) {
|
||||
receiver.useOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||
if (target instanceof CDestructable) {
|
||||
if (target.canBeTargetedBy(game, unit, TREE_ALIVE_TYPE_ONLY)) {
|
||||
receiver.targetOk(target);
|
||||
}
|
||||
else {
|
||||
receiver.mustTargetResources();
|
||||
}
|
||||
}
|
||||
else {
|
||||
receiver.mustTargetResources();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final CWidget target, final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||
innerCheckCanTarget(game, unit, orderId, target, receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityTargetCheckReceiver<Void> receiver) {
|
||||
if ((orderId == OrderIds.returnresources) && isToggleOn()) {
|
||||
receiver.targetOk(null);
|
||||
}
|
||||
else {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
}
|
||||
|
||||
public float getArtAttachmentHeight() {
|
||||
return artAttachmentHeight;
|
||||
}
|
||||
|
||||
public float getPeriodicIntervalLength() {
|
||||
return periodicIntervalLength;
|
||||
}
|
||||
|
||||
public int getPeriodicIntervalLengthTicks() {
|
||||
return periodicIntervalLengthTicks;
|
||||
}
|
||||
|
||||
public int getLumberPerInterval() {
|
||||
return lumberPerInterval;
|
||||
}
|
||||
|
||||
public float getCastRange() {
|
||||
return castRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl;
|
||||
|
||||
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeWispHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeWispHarvestLevelData;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class CAbilityTypeDefinitionWispHarvest extends AbstractCAbilityTypeDefinition<CAbilityTypeWispHarvestLevelData>
|
||||
implements CAbilityTypeDefinition {
|
||||
protected static final War3ID LUMBER_PER_INTERVAL = War3ID.fromString("Wha1");
|
||||
// protected static final War3ID MAYBE_UNUSED = War3ID.fromString("Wha2");
|
||||
protected static final War3ID ART_ATTACHMENT_HEIGHT = War3ID.fromString("Wha3");
|
||||
|
||||
@Override
|
||||
protected CAbilityTypeWispHarvestLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) {
|
||||
final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level);
|
||||
final EnumSet<CTargetType> targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString);
|
||||
final int lumberPerInterval = abilityEditorData.getFieldAsInteger(LUMBER_PER_INTERVAL, level);
|
||||
final float artAttachmentHeight = abilityEditorData.getFieldAsFloat(ART_ATTACHMENT_HEIGHT, level);
|
||||
final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level);
|
||||
final float duration = abilityEditorData.getFieldAsFloat(DURATION, level);
|
||||
return new CAbilityTypeWispHarvestLevelData(targetsAllowedAtLevel, lumberPerInterval, artAttachmentHeight,
|
||||
castRange, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CAbilityType<?> innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData,
|
||||
final List<CAbilityTypeWispHarvestLevelData> levelData) {
|
||||
return new CAbilityTypeWispHarvest(alias, abilityEditorData.getCode(), levelData);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
|
||||
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityWispHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CAbilityTypeWispHarvest extends CAbilityType<CAbilityTypeWispHarvestLevelData> {
|
||||
|
||||
public CAbilityTypeWispHarvest(final War3ID alias, final War3ID code,
|
||||
final List<CAbilityTypeWispHarvestLevelData> levelData) {
|
||||
super(alias, code, levelData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CAbility createAbility(final int handleId) {
|
||||
final CAbilityTypeWispHarvestLevelData levelData = getLevelData(0);
|
||||
return new CAbilityWispHarvest(handleId, getAlias(), levelData.getLumberPerInterval(), levelData.getArtAttachmentHeight(),
|
||||
levelData.getCastRange(), levelData.getDuration());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class CAbilityTypeWispHarvestLevelData extends CAbilityTypeLevelData {
|
||||
private final int lumberPerInterval;
|
||||
private final float artAttachmentHeight;
|
||||
private final float castRange;
|
||||
private final float duration;
|
||||
|
||||
public CAbilityTypeWispHarvestLevelData(final EnumSet<CTargetType> targetsAllowed, final int lumberPerInterval,
|
||||
float artAttachmentHeight, final float castRange, final float duration) {
|
||||
super(targetsAllowed);
|
||||
this.lumberPerInterval = lumberPerInterval;
|
||||
this.artAttachmentHeight = artAttachmentHeight;
|
||||
this.castRange = castRange;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public int getLumberPerInterval() {
|
||||
return lumberPerInterval;
|
||||
}
|
||||
|
||||
public float getArtAttachmentHeight() {
|
||||
return artAttachmentHeight;
|
||||
}
|
||||
|
||||
public float getCastRange() {
|
||||
return this.castRange;
|
||||
}
|
||||
|
||||
public float getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityWispHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor;
|
||||
|
@ -0,0 +1,154 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityWispHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderComponent;
|
||||
|
||||
public class CBehaviorWispHarvest extends CAbstractRangedBehavior {
|
||||
private int lastIncomeTick;
|
||||
private final CAbilityWispHarvest abilityWispHarvest;
|
||||
private boolean harvesting = false;
|
||||
private SimulationRenderComponent spellEffectOverDestructable;
|
||||
|
||||
public CBehaviorWispHarvest(CUnit unit, CAbilityWispHarvest abilityWispHarvest) {
|
||||
super(unit);
|
||||
this.abilityWispHarvest = abilityWispHarvest;
|
||||
}
|
||||
|
||||
public CBehaviorWispHarvest reset(final CWidget target) {
|
||||
innerReset(target, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CBehavior update(CSimulation simulation, boolean withinFacingWindow) {
|
||||
if(target.getX() != unit.getX() || target.getY() != unit.getY()) {
|
||||
unit.setX(target.getX(), simulation.getWorldCollision(), simulation.getRegionManager());
|
||||
unit.setY(target.getY(), simulation.getWorldCollision(), simulation.getRegionManager());
|
||||
simulation.unitRepositioned(unit); // dont interpolate, instant jump
|
||||
}
|
||||
int gameTurnTick = simulation.getGameTurnTick();
|
||||
if (gameTurnTick - lastIncomeTick >= abilityWispHarvest.getPeriodicIntervalLengthTicks()) {
|
||||
lastIncomeTick = gameTurnTick;
|
||||
final CPlayer player = simulation.getPlayer(this.unit.getPlayerIndex());
|
||||
player.setLumber(player.getLumber() + this.abilityWispHarvest.getLumberPerInterval());
|
||||
simulation.unitGainResourceEvent(this.unit, ResourceType.LUMBER,
|
||||
abilityWispHarvest.getLumberPerInterval());
|
||||
}
|
||||
if(!harvesting) {
|
||||
onStartHarvesting(simulation);
|
||||
harvesting = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void onStartHarvesting(CSimulation simulation) {
|
||||
unit.getUnitAnimationListener().addSecondaryTag(AnimationTokens.SecondaryTag.LUMBER);
|
||||
simulation.unitLoopSoundEffectEvent(unit, abilityWispHarvest.getAlias());
|
||||
// TODO maybe use visitor instead of cast
|
||||
spellEffectOverDestructable = simulation.createSpellEffectOverDestructable(this.unit, (CDestructable) this.target, abilityWispHarvest.getAlias(), abilityWispHarvest.getArtAttachmentHeight());
|
||||
simulation.tagTreeOwned((CDestructable)target);
|
||||
}
|
||||
|
||||
private void onStopHarvesting(CSimulation simulation) {
|
||||
unit.getUnitAnimationListener().removeSecondaryTag(AnimationTokens.SecondaryTag.LUMBER);
|
||||
simulation.unitStopSoundEffectEvent(unit, abilityWispHarvest.getAlias());
|
||||
simulation.untagTreeOwned((CDestructable)target);
|
||||
// TODO maybe use visitor instead of cast
|
||||
if(spellEffectOverDestructable != null) {
|
||||
spellEffectOverDestructable.remove();
|
||||
spellEffectOverDestructable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CBehavior updateOnInvalidTarget(CSimulation simulation) {
|
||||
if (this.target instanceof CDestructable) {
|
||||
// wood
|
||||
if(harvesting) {
|
||||
onStopHarvesting(simulation);
|
||||
harvesting = false;
|
||||
}
|
||||
final CDestructable nearestTree = findNearestTree(this.unit, this.abilityWispHarvest,
|
||||
simulation, this.unit);
|
||||
if (nearestTree != null) {
|
||||
return reset(nearestTree);
|
||||
}
|
||||
}
|
||||
return this.unit.pollNextOrderBehavior(simulation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkTargetStillValid(CSimulation simulation) {
|
||||
if(this.target instanceof CDestructable) {
|
||||
if(!harvesting && simulation.isTreeOwned((CDestructable)this.target)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resetBeforeMoving(CSimulation simulation) {
|
||||
if(harvesting) {
|
||||
onStopHarvesting(simulation);
|
||||
harvesting = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRange(CSimulation simulation) {
|
||||
return this.unit.canReach(this.target, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endMove(CSimulation game, boolean interrupted) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(CSimulation game, boolean interrupted) {
|
||||
if(harvesting) {
|
||||
onStopHarvesting(game);
|
||||
harvesting = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return OrderIds.wispharvest;
|
||||
}
|
||||
|
||||
public static CDestructable findNearestTree(final CUnit worker, final CAbilityWispHarvest abilityHarvest,
|
||||
final CSimulation simulation, final CWidget toObject) {
|
||||
CDestructable nearestMine = null;
|
||||
double nearestMineDistance = abilityHarvest.getCastRange()*abilityHarvest.getCastRange();
|
||||
for (final CDestructable unit : simulation.getDestructables()) {
|
||||
if (!unit.isDead()
|
||||
&& !simulation.isTreeOwned(unit)
|
||||
&& unit.canBeTargetedBy(simulation, worker, CAbilityWispHarvest.TREE_ALIVE_TYPE_ONLY)) {
|
||||
final double distance = unit.distanceSquaredNoCollision(toObject);
|
||||
if (distance < nearestMineDistance) {
|
||||
nearestMineDistance = distance;
|
||||
nearestMine = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestMine;
|
||||
}
|
||||
}
|
@ -10,22 +10,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionChannelTest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionColdArrows;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionCoupleInstant;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionGoldMine;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvestLumber;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHumanRepair;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInventory;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemAttackBonus;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemDefenseBonus;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemHeal;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemLifeBonus;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemPermanentStatGain;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemStatBonus;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionReturnResources;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.*;
|
||||
|
||||
public class CAbilityData {
|
||||
|
||||
@ -44,6 +29,7 @@ public class CAbilityData {
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Awha"), new CAbilityTypeDefinitionWispHarvest());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahrl"), new CAbilityTypeDefinitionHarvestLumber());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("ANcl"), new CAbilityTypeDefinitionChannelTest());
|
||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory());
|
||||
|
@ -0,0 +1,5 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||
|
||||
public interface SimulationRenderComponent {
|
||||
void remove();
|
||||
}
|
@ -67,10 +67,15 @@ public interface SimulationRenderController {
|
||||
|
||||
void spawnAbilitySoundEffect(CUnit caster, War3ID alias);
|
||||
|
||||
void loopAbilitySoundEffect(CUnit caster, War3ID alias);
|
||||
|
||||
void stopAbilitySoundEffect(CUnit caster, War3ID alias);
|
||||
|
||||
void unitPreferredSelectionReplacement(CUnit unit, CUnit newUnit);
|
||||
|
||||
void heroRevived(CUnit trainedUnit);
|
||||
|
||||
void heroDeathEvent(CUnit cUnit);
|
||||
|
||||
SimulationRenderComponent createSpellEffectOverDestructable(CUnit source, CDestructable target, War3ID alias, float artAttachmentHeight);
|
||||
}
|
||||
|
@ -171,6 +171,11 @@ public class CommandCardIcon extends AbstractRenderableFrame implements Clickabl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDown(final GameUI gameUI, final Viewport uiViewport) {
|
||||
this.iconFrame.setWidth(this.defaultWidth * 0.95f);
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
@ -25,15 +27,7 @@ import com.etheller.warsmash.networking.WarsmashClientSendingOrderListener;
|
||||
import com.etheller.warsmash.networking.WarsmashClientWriter;
|
||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.EditBoxFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.GlueButtonFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.GlueTextButtonFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.ListBoxFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SetPoint;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.StringFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.UIFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.*;
|
||||
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
|
||||
import com.etheller.warsmash.parsers.w3x.War3Map;
|
||||
import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i;
|
||||
@ -57,6 +51,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMenuData;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMenuUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMission;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.sound.KeyedSounds;
|
||||
import javafx.scene.control.ScrollBar;
|
||||
|
||||
public class MenuUI {
|
||||
private static final Vector2 screenCoordsVector = new Vector2();
|
||||
@ -475,6 +470,39 @@ public class MenuUI {
|
||||
// Create skirmish UI
|
||||
this.skirmish = this.rootFrame.createFrame("Skirmish", this.rootFrame, 0, 0);
|
||||
this.skirmish.setVisible(false);
|
||||
GlueTextButtonFrame playGameButton = (GlueTextButtonFrame)this.rootFrame.getFrameByName("PlayGameButton", 0);
|
||||
SimpleFrame mapListContainer = (SimpleFrame)this.rootFrame.getFrameByName("MapListContainer", 0);
|
||||
final ListBoxFrame mapListBox = (ListBoxFrame) this.rootFrame.createFrameByType("LISTBOX", "MapListBox",
|
||||
mapListContainer, "WITHCHILDREN", 0);
|
||||
mapListBox.setSetAllPoints(true);
|
||||
mapListBox.setFrameFont(profileListText.getFrameFont());
|
||||
Collection<String> listfile = dataSource.getListfile();
|
||||
for(String file: listfile) {
|
||||
if((file.toLowerCase().endsWith(".w3x") || file.toLowerCase().endsWith(".w3m")) && !file.contains("/") && !file.contains("\\")) {
|
||||
mapListBox.addItem(file, this.rootFrame, this.uiViewport);
|
||||
}
|
||||
}
|
||||
mapListContainer.add(mapListBox);
|
||||
playGameButton.setOnClick(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String selectedItem = mapListBox.getSelectedItem();
|
||||
if(selectedItem!=null) {
|
||||
MenuUI.this.campaignMenu.setVisible(false);
|
||||
MenuUI.this.campaignBackButton.setVisible(false);
|
||||
MenuUI.this.missionSelectFrame.setVisible(false);
|
||||
MenuUI.this.campaignSelectFrame.setVisible(false);
|
||||
MenuUI.this.campaignWarcraftIIILogo.setVisible(false);
|
||||
MenuUI.this.campaignRootMenuUI.setVisible(false);
|
||||
MenuUI.this.currentMissionSelectMenuUI.setVisible(false);
|
||||
MenuUI.this.skirmish.setVisible(false);
|
||||
MenuUI.this.glueSpriteLayerTopLeft.setSequence("SinglePlayerSkirmish Birth");
|
||||
MenuUI.this.glueSpriteLayerTopRight.setSequence("SinglePlayerSkirmish Birth");
|
||||
MenuUI.this.mapFilepathToStart = selectedItem;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
this.skirmishCancelButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CancelButton", 0);
|
||||
this.skirmishCancelButton.setOnClick(new Runnable() {
|
||||
@ -1015,7 +1043,11 @@ public class MenuUI {
|
||||
}
|
||||
|
||||
public boolean touchDragged(final int screenX, final int screenY, final float worldScreenY, final int pointer) {
|
||||
mouseMoved(screenX, screenY, worldScreenY);
|
||||
screenCoordsVector.set(screenX, screenY);
|
||||
this.uiViewport.unproject(screenCoordsVector);
|
||||
if(this.mouseDownUIFrame != null) {
|
||||
this.mouseDownUIFrame.mouseDragged(this.rootFrame, this.uiViewport, screenCoordsVector.x, screenCoordsVector.y);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1030,9 +1062,7 @@ public class MenuUI {
|
||||
}
|
||||
if (mousedUIFrame instanceof ClickableFrame) {
|
||||
this.mouseOverUIFrame = (ClickableFrame) mousedUIFrame;
|
||||
if (this.mouseOverUIFrame != null) {
|
||||
this.mouseOverUIFrame.mouseEnter(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
this.mouseOverUIFrame.mouseEnter(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
else {
|
||||
this.mouseOverUIFrame = null;
|
||||
|
@ -87,6 +87,11 @@ public class MultiSelectionIcon extends AbstractRenderableFrame implements Click
|
||||
this.clickListener.multiSelectIconClicked(this.queueIconIndexId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWidth(final float width) {
|
||||
this.defaultWidth = width;
|
||||
|
@ -74,6 +74,11 @@ public class QueueIcon extends AbstractRenderableFrame implements ClickableActio
|
||||
this.clickListener.queueIconClicked(this.queueIconIndexId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWidth(final float width) {
|
||||
this.defaultWidth = width;
|
||||
|
@ -14,4 +14,6 @@ public interface ClickableFrame extends UIFrame {
|
||||
void mouseExit(final GameUI gameUI, final Viewport uiViewport);
|
||||
|
||||
void onClick(int button);
|
||||
|
||||
void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y);
|
||||
}
|
||||
|
@ -91,6 +91,11 @@ public class CampaignButtonUI extends AbstractUIFrame implements ClickableFrame
|
||||
this.buttonArt.onClick(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(GameUI rootFrame, Viewport uiViewport, float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
public void setHeaderText(final StringFrame headerText) {
|
||||
this.headerText = headerText;
|
||||
this.defaultHeaderColor = headerText.getColor();
|
||||
|
Loading…
Reference in New Issue
Block a user