Merge branch 'Card-Forge:master' into master
@@ -17,7 +17,7 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}</directory>
|
||||
|
||||
@@ -2,11 +2,7 @@ package forge.adventure;
|
||||
|
||||
import com.badlogic.gdx.ApplicationListener;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Clipboard;
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window;
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3WindowListener;
|
||||
import com.badlogic.gdx.backends.lwjgl3.*;
|
||||
import com.badlogic.gdx.graphics.glutils.HdpiMode;
|
||||
import forge.Forge;
|
||||
import forge.adventure.util.Config;
|
||||
@@ -107,7 +103,13 @@ public class Main {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
for(int i=0;i<args.length;i++)
|
||||
{
|
||||
if(args[i].equals("testMap"))
|
||||
{
|
||||
Forge.createNewAdventureMap=true;
|
||||
}
|
||||
}
|
||||
new Lwjgl3Application(start, config);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.BiomeData;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class BiomeEdit extends FormPanel {
|
||||
BiomeData currentData;
|
||||
|
||||
public JSpinner startPointX= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner startPointY= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner noiseWeight= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner distWeight= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JTextField name=new JTextField();
|
||||
public FilePicker tilesetAtlas=new FilePicker(new String[]{"atlas"});
|
||||
public JTextField tilesetName=new JTextField();
|
||||
public JSpinner width= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner height= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JTextField color=new JTextField();
|
||||
public JCheckBox collision=new JCheckBox();
|
||||
public TextListEdit spriteNames =new TextListEdit();
|
||||
public TextListEdit enemies =new TextListEdit();
|
||||
public TextListEdit pointsOfInterest =new TextListEdit();
|
||||
|
||||
public TerrainsEditor terrain =new TerrainsEditor();
|
||||
public StructureEditor structures =new StructureEditor();
|
||||
private boolean updating=false;
|
||||
|
||||
public BiomeEdit()
|
||||
{
|
||||
|
||||
FormPanel center=new FormPanel() { };
|
||||
|
||||
center.add("startPointX:",startPointX);
|
||||
center.add("startPointY:",startPointY);
|
||||
center.add("noiseWeight:",noiseWeight);
|
||||
center.add("distWeight:",distWeight);
|
||||
center.add("name:",name);
|
||||
center.add("tilesetAtlas:",tilesetAtlas);
|
||||
center.add("tilesetName:",tilesetName);
|
||||
center.add("width:",width);
|
||||
center.add("height:",height);
|
||||
center.add("spriteNames:",spriteNames);
|
||||
center.add("enemies:",enemies);
|
||||
center.add("pointsOfInterest:",pointsOfInterest);
|
||||
center.add("color:",color);
|
||||
center.add("collision:",collision);
|
||||
center.add("terrain/structures:",new JLabel(""));
|
||||
|
||||
add(center);
|
||||
add(terrain);
|
||||
add(structures);
|
||||
|
||||
name.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
tilesetName.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
color.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
collision.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
spriteNames.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
enemies.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
terrain.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
|
||||
|
||||
startPointX.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
startPointY.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
noiseWeight.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
distWeight.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
tilesetAtlas.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeEdit.this.updateTerrain()));
|
||||
width.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
height.addChangeListener(e -> BiomeEdit.this.updateTerrain());
|
||||
refresh();
|
||||
}
|
||||
|
||||
protected void updateTerrain() {
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.startPointX = (Float) startPointX.getValue();
|
||||
currentData.startPointY = (Float) startPointY.getValue();
|
||||
currentData.noiseWeight = (Float) noiseWeight.getValue();
|
||||
currentData.distWeight = (Float)distWeight.getValue();
|
||||
currentData.name = name.getText();
|
||||
currentData.tilesetAtlas = tilesetAtlas.edit.getText();
|
||||
currentData.tilesetName = tilesetName.getText();
|
||||
currentData.terrain = terrain.getBiomeTerrainData();
|
||||
currentData.structures = structures.getBiomeStructureData();
|
||||
currentData.width = (Float) width.getValue();
|
||||
currentData.height = (Float) height.getValue();
|
||||
currentData.color = color.getText();
|
||||
currentData.collision = collision.isSelected();
|
||||
currentData.spriteNames = spriteNames.getList();
|
||||
currentData.enemies = enemies.getList();
|
||||
currentData.pointsOfInterest = pointsOfInterest.getList();
|
||||
}
|
||||
|
||||
public void setCurrentBiome(BiomeData data)
|
||||
{
|
||||
currentData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
startPointX.setValue(currentData.startPointX);
|
||||
startPointY.setValue(currentData.startPointY);
|
||||
noiseWeight.setValue(currentData.noiseWeight);
|
||||
distWeight.setValue(currentData.distWeight);
|
||||
name.setText(currentData.name);
|
||||
tilesetAtlas.edit.setText( currentData.tilesetAtlas);
|
||||
tilesetName.setText(currentData.tilesetName);
|
||||
terrain.setTerrains(currentData);
|
||||
structures.setStructures(currentData);
|
||||
width.setValue(currentData.width);
|
||||
height.setValue(currentData.height);
|
||||
color.setText(currentData.color);
|
||||
spriteNames.setText(currentData.spriteNames);
|
||||
enemies.setText(currentData.enemies);
|
||||
collision.setSelected(currentData.collision);
|
||||
pointsOfInterest.setText(currentData.pointsOfInterest);
|
||||
updating=false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.BiomeStructureData;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class BiomeStructureDataMappingEditor extends JComponent {
|
||||
DefaultListModel<BiomeStructureData.BiomeStructureDataMapping> model = new DefaultListModel<>();
|
||||
JList<BiomeStructureData.BiomeStructureDataMapping> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
BiomeStructureDataMappingEdit edit=new BiomeStructureDataMappingEdit();
|
||||
private BiomeStructureData data;
|
||||
|
||||
public void setCurrent(BiomeStructureData data) {
|
||||
this.data=data;
|
||||
model.clear();
|
||||
if(data==null||data.mappingInfo==null)
|
||||
return;
|
||||
for(int i=0;i<data.mappingInfo.length;i++)
|
||||
model.addElement(data.mappingInfo[i]);
|
||||
|
||||
list.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
public BiomeStructureData.BiomeStructureDataMapping[] getCurrent()
|
||||
{
|
||||
BiomeStructureData.BiomeStructureDataMapping[] array=new BiomeStructureData.BiomeStructureDataMapping[model.size()];
|
||||
for(int i=0;i<array.length;i++)
|
||||
array[i]=model.get(i);
|
||||
return array;
|
||||
}
|
||||
|
||||
public class BiomeStructureDataMappingRenderer extends DefaultListCellRenderer {
|
||||
private final BiomeStructureDataMappingEditor editor;
|
||||
|
||||
public BiomeStructureDataMappingRenderer(BiomeStructureDataMappingEditor biomeStructureDataMappingEditor) {
|
||||
this.editor=biomeStructureDataMappingEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if(!(value instanceof BiomeStructureData.BiomeStructureDataMapping))
|
||||
return label;
|
||||
BiomeStructureData.BiomeStructureDataMapping data=(BiomeStructureData.BiomeStructureDataMapping) value;
|
||||
// Get the renderer component from parent class
|
||||
|
||||
label.setText(data.name);
|
||||
if(editor.data!=null)
|
||||
{
|
||||
SwingAtlas itemAtlas=new SwingAtlas(Config.instance().getFile(editor.data.structureAtlasPath));
|
||||
if(itemAtlas.has(data.name))
|
||||
label.setIcon(itemAtlas.get(data.name));
|
||||
else
|
||||
{
|
||||
ImageIcon img=itemAtlas.getAny();
|
||||
if(img!=null)
|
||||
label.setIcon(img);
|
||||
}
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
public void addButton(String name, ActionListener action)
|
||||
{
|
||||
JButton newButton=new JButton(name);
|
||||
newButton.addActionListener(action);
|
||||
toolBar.add(newButton);
|
||||
|
||||
}
|
||||
public BiomeStructureDataMappingEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new BiomeStructureDataMappingEditor.BiomeStructureDataMappingRenderer(this));
|
||||
list.addListSelectionListener(e -> BiomeStructureDataMappingEditor.this.updateEdit());
|
||||
addButton("add", e -> BiomeStructureDataMappingEditor.this.add());
|
||||
addButton("remove", e -> BiomeStructureDataMappingEditor.this.remove());
|
||||
addButton("copy", e -> BiomeStructureDataMappingEditor.this.copy());
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(new JScrollPane(list), BorderLayout.WEST);
|
||||
add(toolBar, BorderLayout.NORTH);
|
||||
add(edit,BorderLayout.CENTER);
|
||||
}
|
||||
private void copy() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
BiomeStructureData.BiomeStructureDataMapping data=new BiomeStructureData.BiomeStructureDataMapping(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrent(model.get(selected));
|
||||
}
|
||||
|
||||
void add()
|
||||
{
|
||||
BiomeStructureData.BiomeStructureDataMapping data=new BiomeStructureData.BiomeStructureDataMapping();
|
||||
data.name="Structure "+model.getSize();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
|
||||
private class BiomeStructureDataMappingEdit extends FormPanel{
|
||||
BiomeStructureData.BiomeStructureDataMapping currentData;
|
||||
|
||||
|
||||
public JTextField name=new JTextField();
|
||||
public JTextField color=new JTextField();
|
||||
public JCheckBox collision=new JCheckBox();
|
||||
private boolean updating=false;
|
||||
|
||||
public BiomeStructureDataMappingEdit()
|
||||
{
|
||||
|
||||
|
||||
add("name:",name);
|
||||
add("color:",color);
|
||||
add("collision:",collision);
|
||||
|
||||
name.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeStructureDataMappingEdit.this.update()));
|
||||
color.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeStructureDataMappingEdit.this.update()));
|
||||
collision.addChangeListener(e -> BiomeStructureDataMappingEdit.this.update());
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.name = name.getText();
|
||||
currentData.color = color.getText();
|
||||
currentData.collision = collision.isSelected();
|
||||
}
|
||||
|
||||
public void setCurrent(BiomeStructureData.BiomeStructureDataMapping data)
|
||||
{
|
||||
currentData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
name.setText(currentData.name);
|
||||
color.setText(currentData.color);
|
||||
collision.setSelected(currentData.collision);
|
||||
updating=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeStructureData;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
public class BiomeStructureEdit extends FormPanel {
|
||||
private boolean updating=false;
|
||||
BiomeStructureData currentData;
|
||||
BiomeData currentBiomeData;
|
||||
public JTextField structureAtlasPath=new JTextField();
|
||||
public FloatSpinner x= new FloatSpinner();
|
||||
public FloatSpinner y= new FloatSpinner();
|
||||
public FloatSpinner width= new FloatSpinner();
|
||||
public FloatSpinner height= new FloatSpinner();
|
||||
public JCheckBox randomPosition=new JCheckBox();
|
||||
public IntSpinner N= new IntSpinner();
|
||||
public JTextField sourcePath= new JTextField();
|
||||
public JTextField maskPath= new JTextField();
|
||||
public JCheckBox periodicInput= new JCheckBox();
|
||||
public IntSpinner ground= new IntSpinner();
|
||||
public IntSpinner symmetry= new IntSpinner();
|
||||
public JCheckBox periodicOutput= new JCheckBox();
|
||||
public BiomeStructureDataMappingEditor data=new BiomeStructureDataMappingEditor();
|
||||
public BiomeStructureEdit()
|
||||
{
|
||||
FormPanel center=new FormPanel();
|
||||
|
||||
center.add("structureAtlasPath:",structureAtlasPath);
|
||||
center.add("x:",x);
|
||||
center.add("y:",y);
|
||||
center.add("width:",width);
|
||||
center.add("height:",height);
|
||||
center.add("N:",N);
|
||||
center.add("sourcePath:",sourcePath);
|
||||
center.add("maskPath:",maskPath);
|
||||
center.add("periodicInput:",periodicInput);
|
||||
center.add("ground:",ground);
|
||||
center.add("symmetry:",symmetry);
|
||||
center.add("periodicOutput:",periodicOutput);
|
||||
|
||||
add(center);
|
||||
add(data);
|
||||
|
||||
structureAtlasPath.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeStructureEdit.this.updateStructure()));
|
||||
|
||||
|
||||
x.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
y.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
width.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
height.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
randomPosition.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
|
||||
N.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
sourcePath.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeStructureEdit.this.updateStructure()));
|
||||
maskPath.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeStructureEdit.this.updateStructure()));
|
||||
periodicInput.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
ground.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
symmetry.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
periodicOutput.addChangeListener(e -> BiomeStructureEdit.this.updateStructure());
|
||||
refresh();
|
||||
}
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
data.setCurrent(null);
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
structureAtlasPath.setText(currentData.structureAtlasPath);
|
||||
x.setValue(currentData.x);
|
||||
y.setValue(currentData.y);
|
||||
width.setValue(currentData.width);
|
||||
height.setValue(currentData.height);
|
||||
randomPosition.setSelected(currentData.randomPosition);
|
||||
N.setValue(currentData.N);
|
||||
sourcePath.setText(currentData.sourcePath);
|
||||
maskPath.setText(currentData.maskPath);
|
||||
periodicInput.setSelected(currentData.periodicInput);
|
||||
ground.setValue(currentData.ground);
|
||||
symmetry.setValue(currentData.symmetry);
|
||||
periodicOutput.setSelected(currentData.periodicOutput);
|
||||
|
||||
data.setCurrent(currentData);
|
||||
|
||||
|
||||
|
||||
updating=false;
|
||||
}
|
||||
public void updateStructure()
|
||||
{
|
||||
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.structureAtlasPath=structureAtlasPath.getText();
|
||||
|
||||
currentData.x= x.floatValue();
|
||||
currentData.y= y.floatValue();
|
||||
currentData.width= width.floatValue();
|
||||
currentData.height= height.floatValue();
|
||||
currentData.randomPosition=randomPosition.isSelected();
|
||||
currentData.mappingInfo= data.getCurrent();
|
||||
|
||||
currentData.N= N.intValue();
|
||||
currentData.sourcePath= sourcePath.getText();
|
||||
currentData.maskPath= maskPath.getText();
|
||||
currentData.periodicInput= periodicInput.isSelected();
|
||||
currentData.ground= ground.intValue();
|
||||
currentData.symmetry= symmetry.intValue();
|
||||
currentData.periodicOutput= periodicOutput.isSelected();
|
||||
emitChanged();
|
||||
}
|
||||
public void setCurrentStructure(BiomeStructureData biomeTerrainData, BiomeData data) {
|
||||
currentData =biomeTerrainData;
|
||||
currentBiomeData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void addChangeListener(ChangeListener listener) {
|
||||
listenerList.add(ChangeListener.class, listener);
|
||||
}
|
||||
protected void emitChanged() {
|
||||
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
|
||||
if (listeners != null && listeners.length > 0) {
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners) {
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeTerrainData;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
public class BiomeTerrainEdit extends FormPanel {
|
||||
SwingAtlasPreview preview=new SwingAtlasPreview(128);
|
||||
private boolean updating=false;
|
||||
BiomeTerrainData currentData;
|
||||
BiomeData currentBiomeData;
|
||||
public JTextField spriteName=new JTextField();
|
||||
public JSpinner min= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner max= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
public JSpinner resolution= new JSpinner(new SpinnerNumberModel(0.0f, 0.f, 1f, 0.1f));
|
||||
|
||||
public BiomeTerrainEdit()
|
||||
{
|
||||
FormPanel center=new FormPanel() { };
|
||||
|
||||
center.add("spriteName:",spriteName);
|
||||
center.add("min:",min);
|
||||
center.add("max:",max);
|
||||
center.add("resolution:",resolution);
|
||||
add(center,preview);
|
||||
|
||||
spriteName.getDocument().addDocumentListener(new DocumentChangeListener(() -> BiomeTerrainEdit.this.updateTerrain()));
|
||||
|
||||
min.addChangeListener(e -> BiomeTerrainEdit.this.updateTerrain());
|
||||
max.addChangeListener(e -> BiomeTerrainEdit.this.updateTerrain());
|
||||
resolution.addChangeListener(e -> BiomeTerrainEdit.this.updateTerrain());
|
||||
|
||||
|
||||
refresh();
|
||||
}
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
spriteName.setText(currentData.spriteName);
|
||||
min.setValue(currentData.min);
|
||||
max.setValue(currentData.max);
|
||||
resolution.setValue(currentData.resolution);
|
||||
if(currentBiomeData!=null&¤tData!= null)
|
||||
preview.setSpritePath(currentBiomeData.tilesetAtlas,currentData.spriteName);
|
||||
updating=false;
|
||||
}
|
||||
public void updateTerrain()
|
||||
{
|
||||
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.spriteName=spriteName.getText();
|
||||
currentData.min= (float) min.getValue();
|
||||
currentData.max= (float) max.getValue();
|
||||
currentData.resolution= (float) resolution.getValue();
|
||||
preview.setSpritePath(currentBiomeData.tilesetAtlas,currentData.spriteName);
|
||||
emitChanged();
|
||||
}
|
||||
public void setCurrentTerrain(BiomeTerrainData biomeTerrainData, BiomeData data) {
|
||||
currentData =biomeTerrainData;
|
||||
currentBiomeData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void addChangeListener(ChangeListener listener) {
|
||||
listenerList.add(ChangeListener.class, listener);
|
||||
}
|
||||
protected void emitChanged() {
|
||||
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
|
||||
if (listeners != null && listeners.length > 0) {
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners) {
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import java.awt.*;
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class EditorMainWindow extends JFrame {
|
||||
public final static WorldEditor worldEditor = new WorldEditor();
|
||||
JTabbedPane tabs =new JTabbedPane();
|
||||
|
||||
public EditorMainWindow()
|
||||
@@ -14,8 +15,8 @@ public class EditorMainWindow extends JFrame {
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(tabs);
|
||||
tabs.addTab("World",worldEditor);
|
||||
tabs.addTab("POI",new PointOfInterestEditor());
|
||||
tabs.addTab("World",new WorldEditor());
|
||||
tabs.addTab("Items",new ItemsEditor());
|
||||
tabs.addTab("Enemies",new EnemyEditor());
|
||||
setVisible(true);
|
||||
|
||||
@@ -5,7 +5,6 @@ import forge.adventure.data.EffectData;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
|
||||
public class EffectEditor extends JComponent {
|
||||
EffectData currentData;
|
||||
@@ -25,16 +24,15 @@ public class EffectEditor extends JComponent {
|
||||
if(!isOpponentEffect)
|
||||
opponent=new EffectEditor(true);
|
||||
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
|
||||
JPanel parameters=new JPanel();
|
||||
FormPanel parameters=new FormPanel();
|
||||
parameters.setBorder(BorderFactory.createTitledBorder("Effect"));
|
||||
parameters.setLayout(new GridLayout(7,2)) ;
|
||||
|
||||
parameters.add(new JLabel("Name:")); parameters.add(name);
|
||||
parameters.add(new JLabel("Start with extra cards:")); parameters.add(changeStartCards);
|
||||
parameters.add(new JLabel("Change life:")); parameters.add(lifeModifier);
|
||||
parameters.add(new JLabel("Movement speed:")); parameters.add(moveSpeed);
|
||||
parameters.add(new JLabel("Start battle with cards:")); parameters.add(startBattleWithCard);
|
||||
parameters.add(new JLabel("color view:")); parameters.add(colorView);
|
||||
parameters.add("Name:", name);
|
||||
parameters.add("Start with extra cards:", changeStartCards);
|
||||
parameters.add("Change life:", lifeModifier);
|
||||
parameters.add("Movement speed:", moveSpeed);
|
||||
parameters.add("Start battle with cards:", startBattleWithCard);
|
||||
parameters.add("color view:", colorView);
|
||||
add(parameters);
|
||||
if(!isOpponentEffect)
|
||||
{ add(new JLabel("Opponent:")); add(opponent);}
|
||||
|
||||
@@ -3,21 +3,21 @@ package forge.adventure.editor;
|
||||
import forge.adventure.data.EnemyData;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class EnemyEdit extends JComponent {
|
||||
public class EnemyEdit extends FormPanel {
|
||||
EnemyData currentData;
|
||||
|
||||
|
||||
JTextField nameField=new JTextField();
|
||||
JTextField colorField=new JTextField();
|
||||
JSpinner lifeFiled= new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
|
||||
JSpinner spawnRate= new JSpinner(new SpinnerNumberModel(0.0, 0., 1, 0.1));
|
||||
JSpinner difficulty= new JSpinner(new SpinnerNumberModel(0.0, 0., 1, 0.1));
|
||||
JSpinner speed= new JSpinner(new SpinnerNumberModel(0.0, 0., 100., 1.0));
|
||||
JTextField ai=new JTextField();
|
||||
JCheckBox flying=new JCheckBox();
|
||||
JCheckBox boss=new JCheckBox();
|
||||
FloatSpinner lifeFiled= new FloatSpinner(0, 1000, 1);
|
||||
FloatSpinner spawnRate= new FloatSpinner( 0.f, 1, 0.1f);
|
||||
FloatSpinner difficulty= new FloatSpinner( 0.f, 1, 0.1f);
|
||||
FloatSpinner speed= new FloatSpinner( 0.f, 100.f, 1.0f);
|
||||
FilePicker deck=new FilePicker(new String[]{"dck","json"});
|
||||
FilePicker atlas=new FilePicker(new String[]{"atlas"});
|
||||
JTextField equipment=new JTextField();
|
||||
@@ -28,27 +28,34 @@ public class EnemyEdit extends JComponent {
|
||||
public EnemyEdit()
|
||||
{
|
||||
|
||||
JComponent center=new JComponent() { };
|
||||
center.setLayout(new GridLayout(9,2));
|
||||
FormPanel center=new FormPanel() { };
|
||||
|
||||
center.add(new JLabel("Name:")); center.add(nameField);
|
||||
center.add(new JLabel("Life:")); center.add(lifeFiled);
|
||||
center.add(new JLabel("Spawn rate:")); center.add(spawnRate);
|
||||
center.add(new JLabel("Difficulty:")); center.add(difficulty);
|
||||
center.add(new JLabel("Speed:")); center.add(speed);
|
||||
center.add(new JLabel("Deck:")); center.add(deck);
|
||||
center.add(new JLabel("Sprite:")); center.add(atlas);
|
||||
center.add(new JLabel("Equipment:")); center.add(equipment);
|
||||
center.add(new JLabel("Colors:")); center.add(colorField);
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(center,BorderLayout.PAGE_START);
|
||||
add(rewards,BorderLayout.CENTER);
|
||||
add(preview,BorderLayout.LINE_START);
|
||||
center.add("Name:",nameField);
|
||||
center.add("Life:",lifeFiled);
|
||||
center.add("Spawn rate:",spawnRate);
|
||||
center.add("Difficulty:",difficulty);
|
||||
center.add("Speed:",speed);
|
||||
center.add("Deck:",deck);
|
||||
center.add("Sprite:",atlas);
|
||||
center.add("Equipment:",equipment);
|
||||
center.add("Colors:",colorField);
|
||||
|
||||
center.add("ai:",ai);
|
||||
center.add("flying:",flying);
|
||||
center.add("boss:",boss);
|
||||
|
||||
|
||||
add(preview);
|
||||
add(center);
|
||||
add(rewards);
|
||||
|
||||
equipment.getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
atlas.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
colorField.getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
ai.getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
flying.addChangeListener(e -> EnemyEdit.this.updateEnemy());
|
||||
boss.addChangeListener(e -> EnemyEdit.this.updateEnemy());
|
||||
|
||||
nameField.getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
deck.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> EnemyEdit.this.updateEnemy()));
|
||||
lifeFiled.addChangeListener(e -> EnemyEdit.this.updateEnemy());
|
||||
@@ -65,6 +72,9 @@ public class EnemyEdit extends JComponent {
|
||||
return;
|
||||
currentData.name=nameField.getText();
|
||||
currentData.colors=colorField.getText();
|
||||
currentData.ai=ai.getText();
|
||||
currentData.flying=flying.isSelected();
|
||||
currentData.boss=boss.isSelected();
|
||||
currentData.life= (int) lifeFiled.getValue();
|
||||
currentData.sprite= atlas.getEdit().getText();
|
||||
if(equipment.getText().isEmpty())
|
||||
@@ -94,6 +104,9 @@ public class EnemyEdit extends JComponent {
|
||||
updating=true;
|
||||
nameField.setText(currentData.name);
|
||||
colorField.setText(currentData.colors);
|
||||
ai.setText(currentData.ai);
|
||||
boss.setSelected(currentData.boss);
|
||||
flying.setSelected(currentData.flying);
|
||||
lifeFiled.setValue(currentData.life);
|
||||
atlas.getEdit().setText(currentData.sprite);
|
||||
if(currentData.equipment!=null)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class FloatSpinner extends JSpinner{
|
||||
|
||||
public FloatSpinner()
|
||||
{
|
||||
this( 0.f, 1f, 0.1f);
|
||||
}
|
||||
public FloatSpinner(float min,float max,float stepSize)
|
||||
{
|
||||
super(new SpinnerNumberModel(new Float(0.0f), new Float(min), new Float (max), new Float(stepSize)));
|
||||
}
|
||||
public float floatValue()
|
||||
{
|
||||
return ((Float)getValue()).floatValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class FormPanel extends JPanel {
|
||||
int row=0;
|
||||
static final int MAXIMUM_LINES=300;
|
||||
public FormPanel()
|
||||
{
|
||||
setLayout(new GridBagLayout()) ;
|
||||
|
||||
|
||||
GridBagConstraints constraint=new GridBagConstraints();
|
||||
constraint.weightx = 1.0;
|
||||
constraint.weighty = 1.0;
|
||||
constraint.gridy=MAXIMUM_LINES;
|
||||
constraint.gridx=0;
|
||||
constraint.gridwidth=2;
|
||||
add(Box.createVerticalGlue(),constraint);
|
||||
row++;
|
||||
}
|
||||
public void add(JComponent name,JComponent element)
|
||||
{
|
||||
GridBagConstraints constraint=new GridBagConstraints();
|
||||
constraint.ipadx = 5;
|
||||
constraint.ipady = 5;
|
||||
constraint.weightx = 1.0;
|
||||
constraint.weighty = 0.0;
|
||||
constraint.gridy=row;
|
||||
constraint.gridx=0;
|
||||
constraint.anchor=GridBagConstraints.NORTHWEST;
|
||||
add(name,constraint);
|
||||
constraint.gridy=row;
|
||||
constraint.gridx=1;
|
||||
constraint.fill=GridBagConstraints.HORIZONTAL;
|
||||
constraint.anchor=GridBagConstraints.NORTHEAST;
|
||||
add(element,constraint);
|
||||
|
||||
row++;
|
||||
}
|
||||
public void add(String name,JComponent element)
|
||||
{
|
||||
add(new JLabel(name),element);
|
||||
}
|
||||
public void add(JComponent element)
|
||||
{
|
||||
GridBagConstraints constraint=new GridBagConstraints();
|
||||
constraint.ipadx = 5;
|
||||
constraint.ipady = 5;
|
||||
constraint.weightx = 1.0;
|
||||
constraint.weighty = 0.0;
|
||||
constraint.gridy=row;
|
||||
constraint.gridx=0;
|
||||
constraint.gridwidth=2;
|
||||
constraint.fill=GridBagConstraints.HORIZONTAL;
|
||||
constraint.anchor=GridBagConstraints.NORTHEAST;
|
||||
add(element,constraint);
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
public class IntSpinner extends JSpinner {
|
||||
|
||||
public IntSpinner()
|
||||
{
|
||||
this( 0, 100, 1);
|
||||
}
|
||||
public IntSpinner(int min,int max,int stepSize)
|
||||
{
|
||||
super(new SpinnerNumberModel(new Integer(0), new Integer(min), new Integer (max), new Integer(stepSize)));
|
||||
}
|
||||
public int intValue()
|
||||
{
|
||||
return ((Integer)getValue()).intValue();
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,6 @@ import java.awt.*;
|
||||
*/
|
||||
public class ItemEdit extends JComponent {
|
||||
ItemData currentData;
|
||||
|
||||
|
||||
JTextField nameField=new JTextField();
|
||||
JTextField equipmentSlot=new JTextField();
|
||||
JTextField iconName=new JTextField();
|
||||
@@ -26,19 +24,19 @@ public class ItemEdit extends JComponent {
|
||||
{
|
||||
|
||||
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
|
||||
JPanel parameters=new JPanel();
|
||||
FormPanel parameters=new FormPanel();
|
||||
parameters.setBorder(BorderFactory.createTitledBorder("Parameter"));
|
||||
parameters.setLayout(new GridLayout(6,2)) ;
|
||||
|
||||
parameters.add(new JLabel("Name:")); parameters.add(nameField);
|
||||
parameters.add(new JLabel("equipmentSlot:")); parameters.add(equipmentSlot);
|
||||
parameters.add(new JLabel("description:")); parameters.add(description);
|
||||
parameters.add(new JLabel("iconName")); parameters.add(iconName);
|
||||
parameters.add(new JLabel("questItem")); parameters.add(questItem);
|
||||
parameters.add(new JLabel("cost")); parameters.add(cost);
|
||||
parameters.add("Name:",nameField);
|
||||
parameters.add("equipmentSlot:",equipmentSlot);
|
||||
parameters.add("description:",description);
|
||||
parameters.add("iconName",iconName);
|
||||
parameters.add("questItem",questItem);
|
||||
parameters.add("cost",cost);
|
||||
|
||||
add(parameters);
|
||||
add(effect);
|
||||
add(new Box.Filler(new Dimension(0,0),new Dimension(0,Integer.MAX_VALUE),new Dimension(0,Integer.MAX_VALUE)));
|
||||
|
||||
nameField.getDocument().addDocumentListener(new DocumentChangeListener(() -> ItemEdit.this.updateItem()));
|
||||
equipmentSlot.getDocument().addDocumentListener(new DocumentChangeListener(() -> ItemEdit.this.updateItem()));
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.PointOfInterestData;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class PointOfInterestEdit extends JComponent {
|
||||
|
||||
PointOfInterestData currentData;
|
||||
|
||||
|
||||
JTextField name = new JTextField();
|
||||
JTextField type = new JTextField();
|
||||
JSpinner count = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
|
||||
FilePicker spriteAtlas = new FilePicker(new String[]{"atlas"});
|
||||
JTextField sprite = new JTextField();
|
||||
FilePicker map = new FilePicker(new String[]{"tmx"});
|
||||
JSpinner radiusFactor= new JSpinner(new SpinnerNumberModel(0.0f, 0.0f, 2.0f, 0.1f));
|
||||
|
||||
|
||||
private boolean updating=false;
|
||||
|
||||
public PointOfInterestEdit()
|
||||
{
|
||||
|
||||
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
|
||||
FormPanel parameters=new FormPanel();
|
||||
parameters.setBorder(BorderFactory.createTitledBorder("Parameter"));
|
||||
|
||||
parameters.add("Name:",name);
|
||||
parameters.add("Type:",type);
|
||||
parameters.add("Count:",count);
|
||||
parameters.add("Sprite atlas:",spriteAtlas);
|
||||
parameters.add("Sprite:",sprite);
|
||||
parameters.add("Map:",map);
|
||||
parameters.add("Radius factor:",radiusFactor);
|
||||
|
||||
add(parameters);
|
||||
|
||||
name.getDocument().addDocumentListener(new DocumentChangeListener(() -> PointOfInterestEdit.this.updateItem()));
|
||||
type.getDocument().addDocumentListener(new DocumentChangeListener(() -> PointOfInterestEdit.this.updateItem()));
|
||||
count.addChangeListener(e -> PointOfInterestEdit.this.updateItem());
|
||||
spriteAtlas.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> PointOfInterestEdit.this.updateItem()));
|
||||
sprite.getDocument().addDocumentListener(new DocumentChangeListener(() -> PointOfInterestEdit.this.updateItem()));
|
||||
map.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> PointOfInterestEdit.this.updateItem()));
|
||||
radiusFactor.addChangeListener(e -> PointOfInterestEdit.this.updateItem());
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void updateItem() {
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.name=name.getText();
|
||||
currentData.type= type.getText();
|
||||
currentData.count= ((Integer) count.getValue()).intValue();
|
||||
currentData.spriteAtlas=spriteAtlas.getEdit().getText();
|
||||
currentData.sprite=sprite.getText();
|
||||
currentData.map=map.getEdit().getText();
|
||||
currentData.radiusFactor=((Float) radiusFactor.getValue()).floatValue();
|
||||
}
|
||||
|
||||
public void setCurrent(PointOfInterestData data)
|
||||
{
|
||||
currentData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
name.setText(currentData.name);
|
||||
type.setText(currentData.type);
|
||||
count.setValue(currentData.count);
|
||||
spriteAtlas.getEdit().setText(currentData.spriteAtlas);
|
||||
sprite.setText(currentData.sprite);
|
||||
map.getEdit().setText(currentData.map);
|
||||
radiusFactor.setValue(currentData.radiusFactor);
|
||||
|
||||
updating=false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,131 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonWriter;
|
||||
import forge.adventure.data.PointOfInterestData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
public class PointOfInterestEditor extends Component {
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PointOfInterestEditor extends JComponent {
|
||||
DefaultListModel<PointOfInterestData> model = new DefaultListModel<>();
|
||||
JList<PointOfInterestData> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
PointOfInterestEdit edit=new PointOfInterestEdit();
|
||||
static HashMap<String,SwingAtlas> atlas=new HashMap<>();
|
||||
|
||||
|
||||
|
||||
public class PointOfInterestRenderer extends DefaultListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if(!(value instanceof PointOfInterestData))
|
||||
return label;
|
||||
PointOfInterestData poi=(PointOfInterestData) value;
|
||||
// Get the renderer component from parent class
|
||||
|
||||
label.setText(poi.name);
|
||||
if(!atlas.containsKey(poi.spriteAtlas))
|
||||
atlas.put(poi.spriteAtlas,new SwingAtlas(Config.instance().getFile(poi.spriteAtlas)));
|
||||
|
||||
SwingAtlas poiAtlas = atlas.get(poi.spriteAtlas);
|
||||
|
||||
if(poiAtlas.has(poi.sprite))
|
||||
label.setIcon(poiAtlas.get(poi.sprite));
|
||||
else
|
||||
{
|
||||
ImageIcon img=poiAtlas.getAny();
|
||||
if(img!=null)
|
||||
label.setIcon(img);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
public void addButton(String name, ActionListener action)
|
||||
{
|
||||
JButton newButton=new JButton(name);
|
||||
newButton.addActionListener(action);
|
||||
toolBar.add(newButton);
|
||||
|
||||
}
|
||||
public PointOfInterestEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new PointOfInterestEditor.PointOfInterestRenderer());
|
||||
list.addListSelectionListener(e -> PointOfInterestEditor.this.updateEdit());
|
||||
addButton("add", e -> PointOfInterestEditor.this.addItem());
|
||||
addButton("remove", e -> PointOfInterestEditor.this.remove());
|
||||
addButton("copy", e -> PointOfInterestEditor.this.copy());
|
||||
addButton("load", e -> PointOfInterestEditor.this.load());
|
||||
addButton("save", e -> PointOfInterestEditor.this.save());
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(new JScrollPane(list), BorderLayout.LINE_START);
|
||||
add(toolBar, BorderLayout.PAGE_START);
|
||||
add(edit,BorderLayout.CENTER);
|
||||
load();
|
||||
}
|
||||
private void copy() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
PointOfInterestData data=new PointOfInterestData(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrent(model.get(selected));
|
||||
}
|
||||
|
||||
void save()
|
||||
{
|
||||
Array<PointOfInterestData> allEnemies=new Array<>();
|
||||
for(int i=0;i<model.getSize();i++)
|
||||
allEnemies.add(model.get(i));
|
||||
Json json = new Json(JsonWriter.OutputType.json);
|
||||
FileHandle handle = Config.instance().getFile(Paths.POINTS_OF_INTEREST);
|
||||
handle.writeString(json.prettyPrint(json.toJson(allEnemies,Array.class, PointOfInterestData.class)),false);
|
||||
|
||||
}
|
||||
void load()
|
||||
{
|
||||
model.clear();
|
||||
Array<PointOfInterestData> allEnemies=new Array<>();
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.POINTS_OF_INTEREST);
|
||||
if (handle.exists())
|
||||
{
|
||||
Array readEnemies=json.fromJson(Array.class, PointOfInterestData.class, handle);
|
||||
allEnemies = readEnemies;
|
||||
}
|
||||
for (int i=0;i<allEnemies.size;i++) {
|
||||
model.add(i,allEnemies.get(i));
|
||||
}
|
||||
}
|
||||
void addItem()
|
||||
{
|
||||
PointOfInterestData data=new PointOfInterestData();
|
||||
data.name="PoI "+model.getSize();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,12 @@ import forge.game.keyword.Keyword;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class RewardEdit extends JComponent {
|
||||
public class RewardEdit extends FormPanel {
|
||||
RewardData currentData;
|
||||
|
||||
JComboBox typeField =new JComboBox(new String[] { "card", "gold", "life", "deckCard", "item"});
|
||||
@@ -38,122 +35,41 @@ public class RewardEdit extends JComponent {
|
||||
|
||||
public RewardEdit()
|
||||
{
|
||||
setLayout(new GridLayout(16,2));
|
||||
|
||||
add(new JLabel("Type:")); add(typeField);
|
||||
add(new JLabel("probability:")); add(probability);
|
||||
add(new JLabel("count:")); add(count);
|
||||
add(new JLabel("addMaxCount:")); add(addMaxCount);
|
||||
add(new JLabel("cardName:")); add(cardName);
|
||||
add(new JLabel("itemName:")); add(itemName);
|
||||
add(new JLabel("editions:")); add(editions);
|
||||
add(new JLabel("colors:")); add(colors);
|
||||
add(new JLabel("rarity:")); add(rarity);
|
||||
add(new JLabel("subTypes:")); add(subTypes);
|
||||
add(new JLabel("cardTypes:")); add(cardTypes);
|
||||
add(new JLabel("superTypes:")); add(superTypes);
|
||||
add(new JLabel("manaCosts:")); add(manaCosts);
|
||||
add(new JLabel("keyWords:")); add(keyWords);
|
||||
add(new JLabel("colorType:")); add(colorType);
|
||||
add(new JLabel("cardText:")); add(cardText);
|
||||
add("Type:",typeField);
|
||||
add("probability:",probability);
|
||||
add("count:",count);
|
||||
add("addMaxCount:",addMaxCount);
|
||||
add("cardName:",cardName);
|
||||
add("itemName:",itemName);
|
||||
add("editions:",editions);
|
||||
add("colors:",colors);
|
||||
add("rarity:",rarity);
|
||||
add("subTypes:",subTypes);
|
||||
add("cardTypes:",cardTypes);
|
||||
add("superTypes:",superTypes);
|
||||
add("manaCosts:",manaCosts);
|
||||
add("keyWords:",keyWords);
|
||||
add("colorType:",colorType);
|
||||
add("cardText:",cardText);
|
||||
|
||||
|
||||
typeField.addActionListener((new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
probability.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
});
|
||||
count.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
});
|
||||
addMaxCount.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
});
|
||||
cardName.getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
itemName.getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
editions.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
colors.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
rarity.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
subTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
cardTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
superTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
manaCosts.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
keyWords.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
colorType.addActionListener((new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
cardText.getDocument().addDocumentListener(new DocumentChangeListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RewardEdit.this.updateReward();
|
||||
}
|
||||
}));
|
||||
typeField.addActionListener((e -> RewardEdit.this.updateReward()));
|
||||
probability.addChangeListener(e -> RewardEdit.this.updateReward());
|
||||
count.addChangeListener(e -> RewardEdit.this.updateReward());
|
||||
addMaxCount.addChangeListener(e -> RewardEdit.this.updateReward());
|
||||
cardName.getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
itemName.getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
editions.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
colors.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
rarity.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
subTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
cardTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
superTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
manaCosts.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
keyWords.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
colorType.addActionListener((e -> RewardEdit.this.updateReward()));
|
||||
cardText.getDocument().addDocumentListener(new DocumentChangeListener(() -> RewardEdit.this.updateReward()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@ import forge.adventure.data.RewardData;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
@@ -59,30 +56,10 @@ public class RewardsEditor extends JComponent{
|
||||
{
|
||||
|
||||
list.setCellRenderer(new RewardDataRenderer());
|
||||
list.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
RewardsEditor.this.updateEdit();
|
||||
}
|
||||
});
|
||||
addButton("add", new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RewardsEditor.this.addReward();
|
||||
}
|
||||
});
|
||||
addButton("remove", new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RewardsEditor.this.remove();
|
||||
}
|
||||
});
|
||||
addButton("copy", new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RewardsEditor.this.copy();
|
||||
}
|
||||
});
|
||||
list.addListSelectionListener(e -> RewardsEditor.this.updateEdit());
|
||||
addButton("add", e -> RewardsEditor.this.addReward());
|
||||
addButton("remove", e -> RewardsEditor.this.remove());
|
||||
addButton("copy", e -> RewardsEditor.this.copy());
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(list, BorderLayout.LINE_START);
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeStructureData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.world.BiomeStructure;
|
||||
import forge.adventure.world.ColorMap;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class StructureEditor extends JComponent{
|
||||
DefaultListModel<BiomeStructureData> model = new DefaultListModel<>();
|
||||
JList<BiomeStructureData> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
BiomeStructureEdit edit=new BiomeStructureEdit();
|
||||
|
||||
BiomeData currentData;
|
||||
|
||||
public class StructureDataRenderer extends DefaultListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if(!(value instanceof BiomeStructureData))
|
||||
return label;
|
||||
BiomeStructureData structureData=(BiomeStructureData) value;
|
||||
label.setText("Structure");
|
||||
label.setIcon(new ImageIcon(Config.instance().getFilePath(structureData.sourcePath)));
|
||||
return label;
|
||||
}
|
||||
}
|
||||
public void addButton(String name, ActionListener action)
|
||||
{
|
||||
JButton newButton=new JButton(name);
|
||||
newButton.addActionListener(action);
|
||||
toolBar.add(newButton);
|
||||
|
||||
}
|
||||
|
||||
public StructureEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new StructureDataRenderer());
|
||||
list.addListSelectionListener(e -> StructureEditor.this.updateEdit());
|
||||
addButton("add", e -> StructureEditor.this.addStructure());
|
||||
addButton("remove", e -> StructureEditor.this.remove());
|
||||
addButton("copy", e -> StructureEditor.this.copy());
|
||||
addButton("test", e -> StructureEditor.this.test());
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(list, BorderLayout.WEST);
|
||||
add(toolBar, BorderLayout.NORTH);
|
||||
add(edit,BorderLayout.CENTER);
|
||||
|
||||
|
||||
edit.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
emitChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
protected void emitChanged() {
|
||||
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
|
||||
if (listeners != null && listeners.length > 0) {
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners) {
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void test() {
|
||||
if (list.isSelectionEmpty())
|
||||
return;
|
||||
long start = System.currentTimeMillis();
|
||||
BiomeStructureData data = model.get(list.getSelectedIndex());
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
BiomeStructure struct = new BiomeStructure(data, System.currentTimeMillis(),
|
||||
(int) (currentData.width * EditorMainWindow.worldEditor.width.intValue() ),
|
||||
(int) (currentData.width * EditorMainWindow.worldEditor.height.intValue()));
|
||||
|
||||
BufferedImage sourceImage= null;
|
||||
try {
|
||||
sourceImage = ImageIO.read(new File(struct.sourceImagePath()));
|
||||
ColorMap sourceColorMap=new ColorMap(sourceImage.getWidth(),sourceImage.getHeight());
|
||||
for(int y=0;y<sourceColorMap.getHeight();y++)
|
||||
for(int x=0;x<sourceColorMap.getWidth();x++)
|
||||
{
|
||||
Color c =new Color();
|
||||
Color.argb8888ToColor(c,sourceImage.getRGB(x,y));
|
||||
sourceColorMap.setColor(x,y,c);
|
||||
}
|
||||
|
||||
|
||||
BufferedImage maskImage= ImageIO.read(new File(struct.maskImagePath()));
|
||||
ColorMap maskColorMap=new ColorMap(maskImage.getWidth(),maskImage.getHeight());
|
||||
for(int y=0;y<maskColorMap.getHeight();y++)
|
||||
for(int x=0;x<maskColorMap.getWidth();x++)
|
||||
{
|
||||
Color c =new Color();
|
||||
Color.argb8888ToColor(c,maskImage.getRGB(x,y));
|
||||
maskColorMap.setColor(x,y,c);
|
||||
}
|
||||
|
||||
struct.initialize(sourceColorMap,maskColorMap);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
float calcTime=(System.currentTimeMillis() - start)/1000f;
|
||||
|
||||
JLabel label = new JLabel();
|
||||
ColorMap colorMap=struct.image;
|
||||
BufferedImage image = new BufferedImage(colorMap.getWidth(),colorMap.getHeight(),BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
for(int y=0;y<colorMap.getHeight();y++)
|
||||
for(int x=0;x<colorMap.getWidth();x++)
|
||||
image.setRGB(x,y,Color.argb8888(colorMap.getColor(x,y)));
|
||||
|
||||
if (image.getWidth() < 640 | image.getHeight() < 640) {
|
||||
if (image.getHeight() > image.getWidth()) {
|
||||
BufferedImage nimage = new BufferedImage(640, 640 * (image.getWidth() / image.getHeight()), BufferedImage.TYPE_INT_ARGB);
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.scale(640 / image.getHeight(), 640 / image.getHeight());
|
||||
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
image = scaleOp.filter(image, nimage);
|
||||
} else {
|
||||
BufferedImage nimage = new BufferedImage(640 * (image.getHeight() / image.getWidth()), 640, BufferedImage.TYPE_INT_ARGB);
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.scale(640 / image.getWidth(), 640 / image.getWidth());
|
||||
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
image = scaleOp.filter(image, nimage);
|
||||
}
|
||||
|
||||
}
|
||||
label.setIcon(new ImageIcon(image));
|
||||
label.setSize(640, 640);
|
||||
|
||||
|
||||
|
||||
JOptionPane.showMessageDialog(this, label,"Calculating took "+ calcTime+" seconds",JOptionPane.PLAIN_MESSAGE);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
JOptionPane.showMessageDialog(this, "WaveFunctionCollapse was not successful","can not calculate function "+e.getMessage(),JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
private void copy() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
BiomeStructureData data=new BiomeStructureData(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrentStructure(model.get(selected),currentData);
|
||||
}
|
||||
|
||||
void addStructure()
|
||||
{
|
||||
BiomeStructureData data=new BiomeStructureData();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
public void setStructures(BiomeData data) {
|
||||
|
||||
currentData=data;
|
||||
model.clear();
|
||||
if(data==null||data.structures==null)
|
||||
{
|
||||
edit.setCurrentStructure(null,null);
|
||||
return;
|
||||
}
|
||||
for (int i=0;i<data.structures.length;i++) {
|
||||
model.add(i,data.structures[i]);
|
||||
}
|
||||
list.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
public BiomeStructureData[] getBiomeStructureData() {
|
||||
|
||||
BiomeStructureData[] rewards= new BiomeStructureData[model.getSize()];
|
||||
for(int i=0;i<model.getSize();i++)
|
||||
{
|
||||
rewards[i]=model.get(i);
|
||||
}
|
||||
return rewards;
|
||||
}
|
||||
public void addChangeListener(ChangeListener listener) {
|
||||
listenerList.add(ChangeListener.class, listener);
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,15 @@ import static java.awt.Image.SCALE_FAST;
|
||||
*/
|
||||
public class SwingAtlas {
|
||||
|
||||
int imageSize=32;
|
||||
HashMap<String, ArrayList<ImageIcon>> images=new HashMap<>();
|
||||
public HashMap<String, ArrayList<ImageIcon>> getImages()
|
||||
{
|
||||
return images;
|
||||
}
|
||||
public SwingAtlas(FileHandle path)
|
||||
public SwingAtlas(FileHandle path,int imageSize)
|
||||
{
|
||||
this.imageSize=imageSize;
|
||||
if(!path.exists()||!path.toString().endsWith(".atlas"))
|
||||
return;
|
||||
TextureAtlas.TextureAtlasData data=new TextureAtlas.TextureAtlasData(path,path.parent(),false);
|
||||
@@ -37,20 +39,41 @@ public class SwingAtlas {
|
||||
images.put(name,new ArrayList<>());
|
||||
}
|
||||
ArrayList<ImageIcon> imageList=images.get(name);
|
||||
try {
|
||||
try
|
||||
{
|
||||
imageList.add(spriteToImage(region));
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
public SwingAtlas(FileHandle path)
|
||||
{
|
||||
this(path,32);
|
||||
}
|
||||
|
||||
private ImageIcon spriteToImage(TextureAtlas.TextureAtlasData.Region sprite) throws IOException {
|
||||
try
|
||||
{
|
||||
BufferedImage img = ImageIO.read(sprite.page.textureFile.file());
|
||||
return new ImageIcon(img.getSubimage(sprite.left,sprite.top, sprite.width, sprite.height).getScaledInstance(32,32,SCALE_FAST));
|
||||
if(sprite.width== sprite.height)
|
||||
return new ImageIcon(img.getSubimage(sprite.left,sprite.top, sprite.width, sprite.height).getScaledInstance(imageSize,imageSize,SCALE_FAST));
|
||||
if(sprite.width>sprite.height)
|
||||
return new ImageIcon(img.getSubimage(sprite.left,sprite.top, sprite.width, sprite.height).getScaledInstance(imageSize, (int) (imageSize*(sprite.height/(float)sprite.width)),SCALE_FAST));
|
||||
return new ImageIcon(img.getSubimage(sprite.left,sprite.top, sprite.width, sprite.height).getScaledInstance((int) (imageSize*(sprite.width/(float)sprite.height)),imageSize,SCALE_FAST));
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ImageIcon get(String name) {
|
||||
if(images.get(name).size()==0)
|
||||
return null;
|
||||
return images.get(name).get(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,12 @@ import java.util.Map;
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class SwingAtlasPreview extends Box {
|
||||
int imageSize=32;
|
||||
private String sprite="";
|
||||
private String spriteName="";
|
||||
Timer timer;
|
||||
public SwingAtlasPreview() {
|
||||
super(BoxLayout.Y_AXIS);
|
||||
|
||||
timer = new Timer(200, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -28,25 +29,50 @@ public class SwingAtlasPreview extends Box {
|
||||
}
|
||||
});
|
||||
}
|
||||
public SwingAtlasPreview(int size) {
|
||||
this();
|
||||
imageSize=size;
|
||||
}
|
||||
int counter=0;
|
||||
List<Pair<JLabel,ArrayList<ImageIcon>>> labels=new ArrayList<>();
|
||||
public void setSpritePath(String sprite) {
|
||||
|
||||
if(this.sprite==null||this.sprite.equals(sprite))
|
||||
setSpritePath(sprite,null);
|
||||
}
|
||||
public void setSpritePath(String sprite,String name) {
|
||||
if(this.sprite==null||sprite==null||(this.sprite.equals(sprite)&&(spriteName!=null&&name!=null&&spriteName.equals(name))))
|
||||
return;
|
||||
removeAll();
|
||||
counter=0;
|
||||
labels.clear();
|
||||
this.sprite=sprite;
|
||||
SwingAtlas atlas=new SwingAtlas(Config.instance().getFile(sprite));
|
||||
this.spriteName=name;
|
||||
SwingAtlas atlas=new SwingAtlas(Config.instance().getFile(sprite),imageSize);
|
||||
int maxCount=0;
|
||||
for(Map.Entry<String, ArrayList<ImageIcon>> element:atlas.getImages().entrySet())
|
||||
{
|
||||
if(name==null||element.getKey().equals(name))
|
||||
{
|
||||
JLabel image=new JLabel(element.getValue().get(0));
|
||||
if(maxCount<element.getValue().size())
|
||||
maxCount=element.getValue().size();
|
||||
add(new JLabel(element.getKey()));
|
||||
add(image);
|
||||
labels.add(Pair.of(image, element.getValue()));
|
||||
}
|
||||
}
|
||||
if(maxCount<=1)
|
||||
{
|
||||
timer.stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
timer.restart();
|
||||
}
|
||||
doLayout();
|
||||
revalidate();
|
||||
update(getGraphics());
|
||||
repaint();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeTerrainData;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class TerrainsEditor extends JComponent{
|
||||
DefaultListModel<BiomeTerrainData> model = new DefaultListModel<>();
|
||||
JList<BiomeTerrainData> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
BiomeTerrainEdit edit=new BiomeTerrainEdit();
|
||||
|
||||
BiomeData currentData;
|
||||
|
||||
public class TerrainDataRenderer extends DefaultListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if(!(value instanceof BiomeTerrainData))
|
||||
return label;
|
||||
BiomeTerrainData terrainData=(BiomeTerrainData) value;
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append("Terrain");
|
||||
builder.append(" ");
|
||||
builder.append(terrainData.spriteName);
|
||||
label.setText(builder.toString());
|
||||
return label;
|
||||
}
|
||||
}
|
||||
public void addButton(String name, ActionListener action)
|
||||
{
|
||||
JButton newButton=new JButton(name);
|
||||
newButton.addActionListener(action);
|
||||
toolBar.add(newButton);
|
||||
|
||||
}
|
||||
|
||||
public TerrainsEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new TerrainDataRenderer());
|
||||
list.addListSelectionListener(e -> TerrainsEditor.this.updateEdit());
|
||||
addButton("add", e -> TerrainsEditor.this.addTerrain());
|
||||
addButton("remove", e -> TerrainsEditor.this.remove());
|
||||
addButton("copy", e -> TerrainsEditor.this.copy());
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(list, BorderLayout.LINE_START);
|
||||
add(toolBar, BorderLayout.PAGE_START);
|
||||
add(edit,BorderLayout.CENTER);
|
||||
|
||||
|
||||
edit.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
emitChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
protected void emitChanged() {
|
||||
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
|
||||
if (listeners != null && listeners.length > 0) {
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners) {
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void copy() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
BiomeTerrainData data=new BiomeTerrainData(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrentTerrain(model.get(selected),currentData);
|
||||
}
|
||||
|
||||
void addTerrain()
|
||||
{
|
||||
BiomeTerrainData data=new BiomeTerrainData();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
public void setTerrains(BiomeData data) {
|
||||
|
||||
currentData=data;
|
||||
model.clear();
|
||||
if(data==null||data.terrain==null)
|
||||
return;
|
||||
for (int i=0;i<data.terrain.length;i++) {
|
||||
model.add(i,data.terrain[i]);
|
||||
}
|
||||
list.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
public BiomeTerrainData[] getBiomeTerrainData() {
|
||||
|
||||
BiomeTerrainData[] rewards= new BiomeTerrainData[model.getSize()];
|
||||
for(int i=0;i<model.getSize();i++)
|
||||
{
|
||||
rewards[i]=model.get(i);
|
||||
}
|
||||
return rewards;
|
||||
}
|
||||
public void addChangeListener(ChangeListener listener) {
|
||||
listenerList.add(ChangeListener.class, listener);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@ package forge.adventure.editor;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
@@ -26,6 +28,7 @@ public class TextListEdit extends Box {
|
||||
});
|
||||
|
||||
add(edit);
|
||||
edit.setPreferredSize(new Dimension(400,edit.getPreferredSize().height));
|
||||
//add(findButton);
|
||||
elements= new JComboBox(possibleElements);
|
||||
add(elements);
|
||||
@@ -59,6 +62,12 @@ public class TextListEdit extends Box {
|
||||
}
|
||||
}
|
||||
|
||||
public void setText(List<String> itemNames) {
|
||||
if(itemNames==null)
|
||||
edit.setText("");
|
||||
else
|
||||
edit.setText(String.join(";",itemNames));
|
||||
}
|
||||
public void setText(String[] itemName) {
|
||||
if(itemName==null)
|
||||
edit.setText("");
|
||||
@@ -77,7 +86,7 @@ public class TextListEdit extends Box {
|
||||
{
|
||||
values.append(intValues[i]);
|
||||
if(intValues.length>i+2)
|
||||
values.append(";");
|
||||
values.append("\n");
|
||||
}
|
||||
edit.setText(values.toString());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,226 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonWriter;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.WorldData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
public class WorldEditor extends Component {
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WorldEditor extends JComponent {
|
||||
|
||||
WorldData currentData;
|
||||
|
||||
|
||||
IntSpinner width= new IntSpinner( 0, 100000, 1);
|
||||
IntSpinner height= new IntSpinner( 0, 100000, 1);
|
||||
FloatSpinner playerStartPosX= new FloatSpinner( 0, 1, .1f);
|
||||
FloatSpinner playerStartPosY= new FloatSpinner(0, 1, .1f);
|
||||
FloatSpinner noiseZoomBiome= new FloatSpinner( 0, 1000f, 1f);
|
||||
IntSpinner tileSize= new IntSpinner( 0, 100000, 1);
|
||||
|
||||
JTextField biomesSprites = new JTextField();
|
||||
FloatSpinner maxRoadDistance = new FloatSpinner( 0, 100000f, 1f);
|
||||
TextListEdit biomesNames = new TextListEdit();
|
||||
|
||||
DefaultListModel<BiomeData> model = new DefaultListModel<>();
|
||||
JList<BiomeData> list = new JList<>(model);
|
||||
BiomeEdit edit=new BiomeEdit();
|
||||
JTabbedPane tabs =new JTabbedPane();
|
||||
static HashMap<String,SwingAtlas> atlas=new HashMap<>();
|
||||
|
||||
public class BiomeDataRenderer extends DefaultListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if(!(value instanceof BiomeData))
|
||||
return label;
|
||||
BiomeData biome=(BiomeData) value;
|
||||
// Get the renderer component from parent class
|
||||
|
||||
label.setText(biome.name);
|
||||
if(!atlas.containsKey(biome.tilesetAtlas))
|
||||
atlas.put(biome.tilesetAtlas,new SwingAtlas(Config.instance().getFile(biome.tilesetAtlas)));
|
||||
|
||||
SwingAtlas poiAtlas = atlas.get(biome.tilesetAtlas);
|
||||
|
||||
if(poiAtlas.has(biome.tilesetName))
|
||||
label.setIcon(poiAtlas.get(biome.tilesetName));
|
||||
else
|
||||
{
|
||||
ImageIcon img=poiAtlas.getAny();
|
||||
if(img!=null)
|
||||
label.setIcon(img);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void updateBiome() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrentBiome(model.get(selected));
|
||||
}
|
||||
|
||||
public WorldEditor() {
|
||||
list.setCellRenderer(new BiomeDataRenderer());
|
||||
list.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
WorldEditor.this.updateBiome();
|
||||
}
|
||||
});
|
||||
BorderLayout layout = new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(tabs);
|
||||
JSplitPane biomeData=new JSplitPane();
|
||||
tabs.addTab("BiomeData", biomeData);
|
||||
|
||||
|
||||
FormPanel worldPanel=new FormPanel();
|
||||
worldPanel.add("width:",width);
|
||||
worldPanel.add("height:",height);
|
||||
worldPanel.add("playerStartPosX:",playerStartPosX);
|
||||
worldPanel.add("playerStartPosY:",playerStartPosY);
|
||||
worldPanel.add("noiseZoomBiome:",noiseZoomBiome);
|
||||
worldPanel.add("tileSize:",tileSize);
|
||||
worldPanel.add("biomesSprites:",biomesSprites);
|
||||
worldPanel.add("maxRoadDistance:",maxRoadDistance);
|
||||
worldPanel.add("biomesNames:",biomesNames);
|
||||
tabs.addTab("WorldData", worldPanel);
|
||||
|
||||
|
||||
JScrollPane pane = new JScrollPane(edit);
|
||||
biomeData.setLeftComponent(list); biomeData.setRightComponent(pane);
|
||||
|
||||
load();
|
||||
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
add(toolBar, BorderLayout.PAGE_START);
|
||||
JButton newButton=new JButton("save");
|
||||
newButton.addActionListener(e -> WorldEditor.this.save());
|
||||
toolBar.add(newButton);
|
||||
|
||||
newButton=new JButton("save selected biome");
|
||||
newButton.addActionListener(e -> WorldEditor.this.saveBiome());
|
||||
toolBar.add(newButton);
|
||||
|
||||
newButton=new JButton("load");
|
||||
newButton.addActionListener(e -> WorldEditor.this.load());
|
||||
toolBar.add(newButton);
|
||||
|
||||
toolBar.addSeparator();
|
||||
|
||||
newButton=new JButton("test map");
|
||||
newButton.addActionListener(e -> WorldEditor.this.test());
|
||||
toolBar.add(newButton);
|
||||
}
|
||||
|
||||
private void test() {
|
||||
|
||||
String javaHome = System.getProperty("java.home");
|
||||
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
||||
String classpath = System.getProperty("java.class.path");
|
||||
String className = forge.adventure.Main.class.getName();
|
||||
|
||||
ArrayList<String> command = new ArrayList<>();
|
||||
command.add(javaBin);
|
||||
command.add("-cp");
|
||||
command.add(classpath);
|
||||
command.add(className);
|
||||
|
||||
command.add("testMap");
|
||||
|
||||
ProcessBuilder build= new ProcessBuilder(command);
|
||||
build .redirectInput(ProcessBuilder.Redirect.INHERIT)
|
||||
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
|
||||
.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
try {
|
||||
Process process= build.start();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void saveBiome()
|
||||
{
|
||||
|
||||
edit.updateTerrain();
|
||||
Json json = new Json(JsonWriter.OutputType.json);
|
||||
FileHandle handle = Config.instance().getFile(currentData.biomesNames[list.getSelectedIndex()]);
|
||||
handle.writeString(json.prettyPrint(json.toJson(edit.currentData, BiomeData.class)),false);
|
||||
|
||||
}
|
||||
void save()
|
||||
{
|
||||
currentData.width=width.intValue();
|
||||
currentData.height=height.intValue();
|
||||
currentData.playerStartPosX=playerStartPosX.floatValue();
|
||||
currentData.playerStartPosY=playerStartPosY.floatValue();
|
||||
currentData.noiseZoomBiome=noiseZoomBiome.floatValue();
|
||||
currentData.tileSize=tileSize.intValue();
|
||||
currentData.biomesSprites=biomesSprites.getText();
|
||||
currentData.maxRoadDistance=maxRoadDistance.floatValue();
|
||||
currentData.biomesNames= (biomesNames.getList());
|
||||
|
||||
Json json = new Json(JsonWriter.OutputType.json);
|
||||
FileHandle handle = Config.instance().getFile(Paths.WORLD);
|
||||
handle.writeString(json.prettyPrint(json.toJson(currentData, WorldData.class)),false);
|
||||
|
||||
}
|
||||
void load()
|
||||
{
|
||||
|
||||
|
||||
|
||||
model.clear();
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.WORLD);
|
||||
if (handle.exists())
|
||||
{
|
||||
currentData=json.fromJson(WorldData.class, WorldData.class, handle);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
width.setValue(currentData.width);
|
||||
height.setValue(currentData.height);
|
||||
playerStartPosX.setValue(currentData.playerStartPosX);
|
||||
playerStartPosY.setValue(currentData.playerStartPosY);
|
||||
noiseZoomBiome.setValue(currentData.noiseZoomBiome);
|
||||
tileSize.setValue(currentData.tileSize);
|
||||
biomesSprites.setText(currentData.biomesSprites);
|
||||
maxRoadDistance.setValue(currentData.maxRoadDistance);
|
||||
biomesNames.setText(currentData.biomesNames);
|
||||
|
||||
for(String path:currentData.biomesNames)
|
||||
{
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(path);
|
||||
if (handle.exists())
|
||||
{
|
||||
BiomeData data=json.fromJson(BiomeData.class, BiomeData.class, handle);
|
||||
model.addElement(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,10 +778,13 @@ public class ComputerUtilCost {
|
||||
// Check if the AI intends to play the card and if it can pay for it with the mana it has
|
||||
boolean willPlay = ComputerUtil.hasReasonToPlayCardThisTurn(payer, c);
|
||||
boolean canPay = c.getManaCost().canBePaidWithAvailable(ColorSet.fromNames(getAvailableManaColors(payer, source)).getColor());
|
||||
return canPay && willPlay;
|
||||
if (canPay && willPlay) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,10 +65,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
source.addRemembered(c);
|
||||
}
|
||||
|
||||
if ((power != null) || (toughness != null)) {
|
||||
c.addNewPT(power, toughness, timestamp, 0);
|
||||
}
|
||||
|
||||
if (!addType.isEmpty() || !removeType.isEmpty() || addAllCreatureTypes || removeSuperTypes
|
||||
|| removeCardTypes || removeSubTypes || removeLandTypes || removeCreatureTypes || removeArtifactTypes || removeEnchantmentTypes) {
|
||||
c.addChangedCardTypes(addType, removeType, addAllCreatureTypes, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
@@ -77,6 +73,11 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
|
||||
c.addChangedCardKeywords(keywords, removeKeywords, removeAll, timestamp, 0);
|
||||
|
||||
// do this after changing types in case it wasn't a creature before
|
||||
if (power != null || toughness != null) {
|
||||
c.addNewPT(power, toughness, timestamp, 0);
|
||||
}
|
||||
|
||||
if (sa.hasParam("CantHaveKeyword")) {
|
||||
c.addCantHaveKeyword(timestamp, Keyword.setValueOf(sa.getParam("CantHaveKeyword")));
|
||||
}
|
||||
|
||||
@@ -1131,7 +1131,7 @@ public class CardFactoryUtil {
|
||||
SpellAbility loseLifeSA = AbilityFactory.getAbility(loseLifeStr, card);
|
||||
|
||||
AbilitySub gainLifeSA = (AbilitySub) AbilityFactory.getAbility(gainLifeStr, card);
|
||||
gainLifeSA.setSVar("AFLifeLost", "Number$0");
|
||||
loseLifeSA.setSVar("AFLifeLost", "Number$0");
|
||||
loseLifeSA.setSubAbility(gainLifeSA);
|
||||
loseLifeSA.setIntrinsic(intrinsic);
|
||||
|
||||
|
||||
@@ -1247,12 +1247,17 @@ public class CardView extends GameEntityView {
|
||||
return get(TrackableProperty.Power);
|
||||
}
|
||||
void updatePower(Card c) {
|
||||
if (c.getCurrentState().getView() == this || c.getAlternateState() == null) {
|
||||
set(TrackableProperty.Power, c.getNetPower());
|
||||
int num;
|
||||
if (getType().hasSubtype("Vehicle") && !isCreature()) {
|
||||
// use printed value so user can still see it
|
||||
num = c.getCurrentPower();
|
||||
} else {
|
||||
num = c.getNetPower();
|
||||
}
|
||||
else {
|
||||
set(TrackableProperty.Power, c.getNetPower() - c.getBasePower() + c.getAlternateState().getBasePower());
|
||||
if (c.getCurrentState().getView() != this && c.getAlternateState() != null) {
|
||||
num -= c.getBasePower() + c.getAlternateState().getBasePower();
|
||||
}
|
||||
set(TrackableProperty.Power, num);
|
||||
}
|
||||
void updatePower(CardState c) {
|
||||
Card card = c.getCard();
|
||||
@@ -1267,12 +1272,17 @@ public class CardView extends GameEntityView {
|
||||
return get(TrackableProperty.Toughness);
|
||||
}
|
||||
void updateToughness(Card c) {
|
||||
if (c.getCurrentState().getView() == this || c.getAlternateState() == null) {
|
||||
set(TrackableProperty.Toughness, c.getNetToughness());
|
||||
int num;
|
||||
if (getType().hasSubtype("Vehicle") && !isCreature()) {
|
||||
// use printed value so user can still see it
|
||||
num = c.getCurrentToughness();
|
||||
} else {
|
||||
num = c.getNetToughness();
|
||||
}
|
||||
else {
|
||||
set(TrackableProperty.Toughness, c.getNetToughness() - c.getBaseToughness() + c.getAlternateState().getBaseToughness());
|
||||
if (c.getCurrentState().getView() != this && c.getAlternateState() != null) {
|
||||
num -= c.getBaseToughness() + c.getAlternateState().getBaseToughness();
|
||||
}
|
||||
set(TrackableProperty.Toughness, num);
|
||||
}
|
||||
void updateToughness(CardState c) {
|
||||
Card card = c.getCard();
|
||||
|
||||
@@ -123,6 +123,7 @@ public class Forge implements ApplicationListener {
|
||||
private static Cursor cursor0, cursor1, cursor2, cursorA0, cursorA1, cursorA2;
|
||||
public static boolean forcedEnglishonCJKMissing = false;
|
||||
public static boolean adventureLoaded = false;
|
||||
public static boolean createNewAdventureMap = false;
|
||||
private static Localizer localizer;
|
||||
|
||||
public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0, boolean value, boolean androidOrientation, int totalRAM, boolean isTablet, int AndroidAPI, String AndroidRelease, String deviceName) {
|
||||
@@ -328,6 +329,9 @@ public class Forge implements ApplicationListener {
|
||||
altZoneTabs = true;
|
||||
//pixl cursor for adventure
|
||||
setCursor(null, "0");
|
||||
loadAdventureResources(true);
|
||||
}
|
||||
private static void loadAdventureResources(boolean startScene) {
|
||||
try {
|
||||
if(!adventureLoaded)
|
||||
{
|
||||
@@ -336,6 +340,7 @@ public class Forge implements ApplicationListener {
|
||||
}
|
||||
adventureLoaded=true;
|
||||
}
|
||||
if (startScene)
|
||||
switchScene(SceneType.StartScene.instance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -362,8 +367,16 @@ public class Forge implements ApplicationListener {
|
||||
//load Drafts
|
||||
preloadBoosterDrafts();
|
||||
FThreads.invokeInEdtLater(() -> {
|
||||
if (selector.equals("Adventure")) {
|
||||
//preload adventure resources to speedup startup if selector is adventure. Needs in edt when setting up worldstage
|
||||
loadAdventureResources(false);
|
||||
}
|
||||
//selection transition
|
||||
setTransitionScreen(new TransitionScreen(() -> {
|
||||
if (createNewAdventureMap) {
|
||||
openAdventure();
|
||||
clearSplashScreen();
|
||||
} else {
|
||||
if (selector.equals("Classic")) {
|
||||
openHomeDefault();
|
||||
clearSplashScreen();
|
||||
@@ -376,6 +389,7 @@ public class Forge implements ApplicationListener {
|
||||
openHomeDefault();
|
||||
clearSplashScreen();
|
||||
}
|
||||
}
|
||||
//start background music
|
||||
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);
|
||||
safeToClose = true;
|
||||
@@ -887,6 +901,8 @@ public class Forge implements ApplicationListener {
|
||||
//check if sentry is enabled, if not it will call the gui interface but here we end the graphics so we only send it via sentry..
|
||||
if (BugReporter.isSentryEnabled())
|
||||
BugReporter.reportException(ex);
|
||||
else
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (showFPS)
|
||||
frameRate.render();
|
||||
@@ -944,10 +960,10 @@ public class Forge implements ApplicationListener {
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (currentScreen != null) {
|
||||
FOverlay.hideAll();
|
||||
currentScreen.onClose(null);
|
||||
currentScreen = null;
|
||||
}
|
||||
FOverlay.hideAll();
|
||||
assets.dispose();
|
||||
Dscreens.clear();
|
||||
graphics.dispose();
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.Animation;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.graphics.g2d.*;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@@ -38,7 +33,7 @@ public class CharacterSprite extends MapActor {
|
||||
|
||||
@Override
|
||||
void updateBoundingRect() { //We want a slimmer box for the player entity so it can navigate terrain without getting stuck.
|
||||
boundingRect = new Rectangle(getX() + 4, getY(), getWidth() - 6, getHeight() * collisionHeight);
|
||||
boundingRect.set(getX() + 4, getY(), getWidth() - 6, getHeight() * collisionHeight);
|
||||
}
|
||||
|
||||
protected void load(String path) {
|
||||
@@ -61,8 +56,14 @@ public class CharacterSprite extends MapActor {
|
||||
anim = atlas.createSprites(stand.toString());
|
||||
else
|
||||
anim = atlas.createSprites(stand.toString() + dir.toString());
|
||||
|
||||
if (anim.size != 0) {
|
||||
dirs.put(dir, new Animation<>(0.2f, anim));
|
||||
if(getWidth()==0.0)//init size onload
|
||||
{
|
||||
setWidth(anim.first().getWidth());
|
||||
setHeight(anim.first().getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
animations.put(stand, dirs);
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@@ -50,7 +49,7 @@ public class EnemySprite extends CharacterSprite {
|
||||
|
||||
@Override
|
||||
void updateBoundingRect() { //We want enemies to take the full tile.
|
||||
boundingRect = new Rectangle(getX(), getY(), getWidth(), getHeight());
|
||||
boundingRect.set(getX(), getY(), getWidth(), getHeight());
|
||||
}
|
||||
|
||||
public void moveTo(Actor other, float delta) {
|
||||
@@ -182,5 +181,8 @@ public class EnemySprite extends CharacterSprite {
|
||||
}
|
||||
}
|
||||
|
||||
public float speed() {
|
||||
return data.speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public class MapActor extends Actor {
|
||||
|
||||
|
||||
Texture debugTexture;
|
||||
float collisionHeight=1.0f;
|
||||
protected float collisionHeight=1.0f;
|
||||
final int objectId;
|
||||
public MapActor(int objectId)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ public class MapActor extends Actor {
|
||||
}
|
||||
return debugTexture;
|
||||
}
|
||||
Rectangle boundingRect;
|
||||
final Rectangle boundingRect=new Rectangle();
|
||||
|
||||
boolean isCollidingWithPlayer=false;
|
||||
protected void onPlayerCollide()
|
||||
@@ -55,9 +55,8 @@ public class MapActor extends Actor {
|
||||
}
|
||||
@Override
|
||||
protected void positionChanged() {
|
||||
|
||||
updateBoundingRect();
|
||||
super.positionChanged();
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +66,7 @@ public class MapActor extends Actor {
|
||||
}
|
||||
|
||||
void updateBoundingRect() {
|
||||
boundingRect = new Rectangle(getX(), getY(), getWidth(), getHeight()*collisionHeight);
|
||||
boundingRect.set(getX(), getY(), getWidth(), getHeight()*collisionHeight);
|
||||
}
|
||||
|
||||
public Rectangle boundingRect() {
|
||||
@@ -106,4 +105,8 @@ public class MapActor extends Actor {
|
||||
return boundingRect.x < other.getX() + other.getWidth() && boundingRect.x + boundingRect.width > other.getX() && boundingRect.y < other.getY() + other.getHeight() && boundingRect.y + boundingRect.height > other.getY();
|
||||
|
||||
}
|
||||
|
||||
public float getCollisionHeight() {
|
||||
return collisionHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.data.RewardData;
|
||||
import forge.adventure.util.JSONStringLoader;
|
||||
@@ -40,7 +39,7 @@ public class RewardSprite extends CharacterSprite {
|
||||
|
||||
@Override
|
||||
void updateBoundingRect() { //We want rewards to take a full tile.
|
||||
boundingRect = new Rectangle(getX(), getY(), getWidth(), getHeight());
|
||||
boundingRect.set(getX(), getY(), getWidth(), getHeight());
|
||||
}
|
||||
|
||||
public Array<Reward> getRewards() { //Get list of rewards.
|
||||
|
||||
@@ -6,7 +6,6 @@ import forge.util.MyRandom;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@@ -15,7 +14,6 @@ import java.util.Random;
|
||||
* contains the information for the biomes
|
||||
*/
|
||||
public class BiomeData implements Serializable {
|
||||
private final Random rand = MyRandom.getRandom();
|
||||
public float startPointX;
|
||||
public float startPointY;
|
||||
public float noiseWeight;
|
||||
@@ -27,14 +25,17 @@ public class BiomeData implements Serializable {
|
||||
public float width;
|
||||
public float height;
|
||||
public String color;
|
||||
public boolean collision;
|
||||
public boolean invertHeight;
|
||||
public String[] spriteNames;
|
||||
public List<String> enemies;
|
||||
public List<String> pointsOfInterest;
|
||||
public String[] enemies;
|
||||
public String[] pointsOfInterest;
|
||||
public BiomeStructureData[] structures;
|
||||
|
||||
private ArrayList<EnemyData> enemyList;
|
||||
private ArrayList<PointOfInterestData> pointOfInterestList;
|
||||
|
||||
private final Random rand = MyRandom.getRandom();
|
||||
public Color GetColor() {
|
||||
return Color.valueOf(color);
|
||||
}
|
||||
@@ -45,8 +46,13 @@ public class BiomeData implements Serializable {
|
||||
if (enemies == null)
|
||||
return enemyList;
|
||||
for (EnemyData data : new Array.ArrayIterator<>(WorldData.getAllEnemies())) {
|
||||
if (enemies.contains(data.name)) {
|
||||
for (String enemyName:enemies)
|
||||
{
|
||||
if(data.name.equals(enemyName))
|
||||
{
|
||||
enemyList.add(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,8 +66,13 @@ public class BiomeData implements Serializable {
|
||||
return pointOfInterestList;
|
||||
Array<PointOfInterestData> allTowns = PointOfInterestData.getAllPointOfInterest();
|
||||
for (PointOfInterestData data : new Array.ArrayIterator<>(allTowns)) {
|
||||
if (pointsOfInterest.contains(data.name)) {
|
||||
for (String poiName:pointsOfInterest)
|
||||
{
|
||||
if(data.name.equals(poiName))
|
||||
{
|
||||
pointOfInterestList.add(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
public class BiomeStructureData {
|
||||
|
||||
|
||||
static public class BiomeStructureDataMapping
|
||||
{
|
||||
public int getColor() {
|
||||
return ((Integer.parseInt(color,16)<<8)|0xff);
|
||||
}
|
||||
public String name;
|
||||
public String color;
|
||||
public boolean collision;
|
||||
|
||||
public BiomeStructureDataMapping() {
|
||||
|
||||
}
|
||||
public BiomeStructureDataMapping(BiomeStructureDataMapping biomeStructureDataMapping) {
|
||||
this.name=biomeStructureDataMapping.name;
|
||||
this.color=biomeStructureDataMapping.color;
|
||||
this.collision=biomeStructureDataMapping.collision;
|
||||
}
|
||||
}
|
||||
public int N = 3;
|
||||
public float x;
|
||||
public float y;
|
||||
public boolean randomPosition;
|
||||
|
||||
public String structureAtlasPath;
|
||||
public String sourcePath;
|
||||
public String maskPath;
|
||||
public boolean periodicInput=true;
|
||||
public float height;
|
||||
public float width;
|
||||
public int ground;
|
||||
public int symmetry=2;
|
||||
public boolean periodicOutput=true;
|
||||
public BiomeStructureDataMapping[] mappingInfo;
|
||||
|
||||
public BiomeStructureData( ) {
|
||||
|
||||
}
|
||||
public BiomeStructureData(BiomeStructureData biomeStructureData) {
|
||||
this.structureAtlasPath=biomeStructureData.structureAtlasPath;
|
||||
this.sourcePath=biomeStructureData.sourcePath;
|
||||
this.maskPath=biomeStructureData.maskPath;
|
||||
this.x=biomeStructureData.x;
|
||||
this.y=biomeStructureData.y;
|
||||
this.width=biomeStructureData.width;
|
||||
this.height=biomeStructureData.height;
|
||||
this.randomPosition=biomeStructureData.randomPosition;
|
||||
if(biomeStructureData.mappingInfo!=null)
|
||||
{
|
||||
this.mappingInfo=new BiomeStructureDataMapping[ biomeStructureData.mappingInfo.length];
|
||||
for(int i=0;i<biomeStructureData.mappingInfo.length;i++)
|
||||
this.mappingInfo[i]=new BiomeStructureDataMapping(biomeStructureData.mappingInfo[i]);
|
||||
}
|
||||
else
|
||||
this.mappingInfo=null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,4 +16,16 @@ public class BiomeTerrainData {
|
||||
// factor for the noise resolution
|
||||
public float resolution;
|
||||
|
||||
public BiomeTerrainData()
|
||||
{
|
||||
|
||||
}
|
||||
public BiomeTerrainData(BiomeTerrainData other)
|
||||
{
|
||||
spriteName=other.spriteName;
|
||||
min=other.min;
|
||||
max=other.max;
|
||||
resolution=other.resolution;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
@@ -19,6 +17,6 @@ public class ConfigData {
|
||||
public String[] starterDecks;
|
||||
public DifficultyData[] difficulties;
|
||||
public RewardData legalCards;
|
||||
public List<String> restrictedCards;
|
||||
public List<String> restrictedEditions;
|
||||
public String[] restrictedCards;
|
||||
public String[] restrictedEditions;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class EnemyData {
|
||||
public boolean copyPlayerDeck = false;
|
||||
public String ai;
|
||||
public boolean boss = false;
|
||||
public boolean flying = false;
|
||||
public float spawnRate;
|
||||
public float difficulty;
|
||||
public float speed;
|
||||
@@ -30,6 +31,7 @@ public class EnemyData {
|
||||
deck = enemyData.deck;
|
||||
ai = enemyData.ai;
|
||||
boss = enemyData.boss;
|
||||
flying = enemyData.flying;
|
||||
spawnRate = enemyData.spawnRate;
|
||||
copyPlayerDeck = enemyData.copyPlayerDeck;
|
||||
difficulty = enemyData.difficulty;
|
||||
|
||||
@@ -42,4 +42,18 @@ public class PointOfInterestData {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public PointOfInterestData()
|
||||
{
|
||||
|
||||
}
|
||||
public PointOfInterestData(PointOfInterestData other)
|
||||
{
|
||||
name=other.name;
|
||||
type=other.type;
|
||||
count=other.count;
|
||||
spriteAtlas=other.spriteAtlas;
|
||||
sprite=other.sprite;
|
||||
map=other.map;
|
||||
radiusFactor=other.radiusFactor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -75,8 +76,8 @@ public class RewardData {
|
||||
@Override
|
||||
public boolean apply(PaperCard input){
|
||||
if(input == null) return false;
|
||||
if(Config.instance().getConfigData().restrictedEditions.contains(input.getEdition())) return false;
|
||||
return !Config.instance().getConfigData().restrictedCards.contains(input.getName());
|
||||
if(Arrays.asList(Config.instance().getConfigData().restrictedEditions).contains(input.getEdition())) return false;
|
||||
return !Arrays.asList(Config.instance().getConfigData().restrictedCards).contains(input.getName());
|
||||
}
|
||||
});
|
||||
//Filter AI cards for enemies.
|
||||
|
||||
@@ -14,4 +14,8 @@ public class SettingData {
|
||||
public boolean fullScreen;
|
||||
public String videomode;
|
||||
public String lastActiveSave;
|
||||
public Float rewardCardAdj;
|
||||
public Float cardTooltipAdj;
|
||||
public Float rewardCardAdjLandscape;
|
||||
public Float cardTooltipAdjLandscape;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.OrderedMap;
|
||||
|
||||
/**
|
||||
@@ -12,5 +11,5 @@ public class UIData {
|
||||
public int width;
|
||||
public int height;
|
||||
public boolean yDown;
|
||||
public Array<OrderedMap<String,String>> elements;
|
||||
public OrderedMap<String,String>[] elements;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.adventure.data;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.SerializationException;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
import forge.adventure.world.BiomeSprites;
|
||||
@@ -17,19 +18,22 @@ import java.util.List;
|
||||
*/
|
||||
public class WorldData implements Serializable {
|
||||
|
||||
static Array<EnemyData> allEnemies;
|
||||
public int width;
|
||||
public int height;
|
||||
public float playerStartPosX;
|
||||
public float playerStartPosY;
|
||||
public float noiseZoomBiome;
|
||||
public int tileSize;
|
||||
public List<String> biomesNames;
|
||||
public BiomeData roadTileset;
|
||||
public String biomesSprites;
|
||||
public float maxRoadDistance;
|
||||
public String[] biomesNames;
|
||||
|
||||
|
||||
private BiomeSprites sprites;
|
||||
private List<BiomeData> biomes;
|
||||
|
||||
private static Array<EnemyData> allEnemies;
|
||||
private static Array<ShopData> shopList;
|
||||
|
||||
|
||||
@@ -77,12 +81,18 @@ public class WorldData implements Serializable {
|
||||
|
||||
public List<BiomeData> GetBiomes() {
|
||||
if (biomes == null) {
|
||||
try
|
||||
{
|
||||
biomes = new ArrayList<BiomeData>();
|
||||
Json json = new Json();
|
||||
for (String name : biomesNames) {
|
||||
biomes.add(json.fromJson(BiomeData.class, Config.instance().getFile(name)));
|
||||
}
|
||||
}
|
||||
catch (SerializationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.adventure.data.*;
|
||||
import forge.adventure.data.DifficultyData;
|
||||
import forge.adventure.data.EffectData;
|
||||
import forge.adventure.data.HeroListData;
|
||||
import forge.adventure.data.ItemData;
|
||||
import forge.adventure.util.*;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.deck.CardPool;
|
||||
@@ -18,7 +21,10 @@ import forge.util.ItemPool;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class that represents the player (not the player sprite)
|
||||
|
||||
@@ -9,18 +9,10 @@ import forge.adventure.player.AdventurePlayer;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.FSkinImage;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckFormat;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.deck.FDeckViewer;
|
||||
import forge.deck.*;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.CardManager;
|
||||
import forge.itemmanager.ColumnDef;
|
||||
import forge.itemmanager.ItemColumn;
|
||||
import forge.itemmanager.ItemManager;
|
||||
import forge.itemmanager.ItemManagerConfig;
|
||||
import forge.itemmanager.*;
|
||||
import forge.itemmanager.filters.ItemFilter;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.menu.FCheckBoxMenuItem;
|
||||
|
||||
@@ -3,12 +3,7 @@ package forge.adventure.scene;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
|
||||
@@ -4,13 +4,7 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@@ -228,6 +222,20 @@ public class NewGameScene extends UIScene {
|
||||
public void enter() {
|
||||
updateAvatar();
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
|
||||
if(Forge.createNewAdventureMap)
|
||||
{
|
||||
FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false);
|
||||
WorldSave.generateNewWorld(selectedName.getText(),
|
||||
gender.getCurrentIndex() == 0,
|
||||
race.getCurrentIndex(),
|
||||
avatarIndex,
|
||||
deck.getCurrentIndex(),
|
||||
Config.instance().getConfigData().difficulties[difficulty.getCurrentIndex()],
|
||||
fantasyMode, easyMode, deck.getText(), 0);
|
||||
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
|
||||
Forge.switchScene(SceneType.GameScene.instance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,11 +4,7 @@ import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import forge.Forge;
|
||||
|
||||
@@ -13,10 +13,7 @@ import forge.adventure.character.ShopActor;
|
||||
import forge.adventure.player.AdventurePlayer;
|
||||
import forge.adventure.pointofintrest.PointOfInterestChanges;
|
||||
import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.util.CardUtil;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.Reward;
|
||||
import forge.adventure.util.RewardActor;
|
||||
import forge.adventure.util.*;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.assets.ImageCache;
|
||||
import forge.sound.SoundEffectType;
|
||||
@@ -222,22 +219,29 @@ public class RewardScene extends UIScene {
|
||||
float mul = fW/fH < AR ? AR/(fW/fH) : (fW/fH)/AR;
|
||||
if (fW/fH >= 2f) {//tall display
|
||||
mul = (fW/fH) - ((fW/fH)/AR);
|
||||
if ((fW/fH) >= 2.1f && (fW/fH) < 2.3f)
|
||||
if ((fW/fH) >= 2.1f && (fW/fH) < 2.2f)
|
||||
mul *= 0.9f;
|
||||
else if ((fW/fH) > 2.3) //ultrawide 21:9 Galaxy Fold, Huawei X2, Xperia 1
|
||||
else if ((fW/fH) > 2.2f) //ultrawide 21:9 Galaxy Fold, Huawei X2, Xperia 1
|
||||
mul *= 0.8f;
|
||||
}
|
||||
cardHeight = bestCardHeight * 0.90f ;
|
||||
Float custom = Forge.isLandscapeMode() ? Config.instance().getSettingData().rewardCardAdjLandscape : Config.instance().getSettingData().rewardCardAdj;
|
||||
if (custom != null && custom != 1f) {
|
||||
mul *= custom;
|
||||
} else {
|
||||
if (realX > x || realY > y) {
|
||||
mul *= Forge.isLandscapeMode() ? 0.95f : 1.05f;
|
||||
} else {
|
||||
//immersive | no navigation and/or showing cutout cam
|
||||
if (fW/fH > 2.3f)
|
||||
if (fW/fH > 2.2f)
|
||||
mul *= Forge.isLandscapeMode() ? 1.1f : 1.6f;
|
||||
else if (fW/fH > 2f)
|
||||
mul *= Forge.isLandscapeMode() ? 1.1f : 1.5f;
|
||||
else if (fW/fH >= 2.1f)
|
||||
mul *= Forge.isLandscapeMode() ? 1.05f : 1.5f;
|
||||
else if (fW/fH >= 2f)
|
||||
mul *= Forge.isLandscapeMode() ? 1f : 1.4f;
|
||||
|
||||
}
|
||||
}
|
||||
cardWidth = (cardHeight / CARD_WIDTH_TO_HEIGHT)*mul;
|
||||
|
||||
yOff += (targetHeight - (cardHeight * numberOfRows)) / 2f;
|
||||
|
||||
@@ -16,8 +16,6 @@ import forge.gui.GuiBase;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Scene to handle settings of the base forge and adventure mode
|
||||
*/
|
||||
@@ -118,12 +116,7 @@ public class SettingsScene extends UIScene {
|
||||
|
||||
private void addSettingField(String name, int value, ChangeListener change) {
|
||||
TextField text = Controls.newTextField(String.valueOf(value));
|
||||
text.setTextFieldFilter(new TextField.TextFieldFilter() {
|
||||
@Override
|
||||
public boolean acceptChar(TextField textField, char c) {
|
||||
return Character.isDigit(c);
|
||||
}
|
||||
});
|
||||
text.setTextFieldFilter((textField, c) -> Character.isDigit(c));
|
||||
text.addListener(change);
|
||||
addLabel(name);
|
||||
settingGroup.add(text).align(Align.right);
|
||||
@@ -145,21 +138,16 @@ public class SettingsScene extends UIScene {
|
||||
Preference = new ForgePreferences();
|
||||
}
|
||||
|
||||
SelectBox plane = Controls.newComboBox(Config.instance().getAllAdventures(), Config.instance().getSettingData().plane, new Function<Object, Void>() {
|
||||
@Override
|
||||
public Void apply(Object o) {
|
||||
SelectBox plane = Controls.newComboBox(Config.instance().getAllAdventures(), Config.instance().getSettingData().plane, o -> {
|
||||
Config.instance().getSettingData().plane = (String) o;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
addLabel(Forge.getLocalizer().getMessage("lblWorld"));
|
||||
settingGroup.add(plane).align(Align.right).pad(2);
|
||||
|
||||
if (!GuiBase.isAndroid()) {
|
||||
SelectBox videomode = Controls.newComboBox(new String[]{"720p", "768p", "900p", "1080p"}, Config.instance().getSettingData().videomode, new Function<Object, Void>() {
|
||||
@Override
|
||||
public Void apply(Object o) {
|
||||
SelectBox videomode = Controls.newComboBox(new String[]{"720p", "768p", "900p", "1080p"}, Config.instance().getSettingData().videomode, o -> {
|
||||
String mode = (String) o;
|
||||
if (mode == null)
|
||||
mode = "720p";
|
||||
@@ -184,10 +172,56 @@ public class SettingsScene extends UIScene {
|
||||
FModel.getPreferences().save();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
addLabel(Forge.getLocalizer().getMessage("lblVideoMode"));
|
||||
settingGroup.add(videomode).align(Align.right).pad(2);
|
||||
}
|
||||
if (Forge.isLandscapeMode()) {
|
||||
//different adjustment to landscape
|
||||
SelectBox rewardCardAdjLandscape = Controls.newComboBox(new Float[]{0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 1f, 1.05f, 1.1f, 1.15f, 1.2f, 1.25f, 1.3f, 1.35f, 1.4f, 1.45f, 1.5f, 1.55f, 1.6f}, Config.instance().getSettingData().rewardCardAdjLandscape, o -> {
|
||||
Float val = (Float) o;
|
||||
if (val == null || val == 0f)
|
||||
val = 1f;
|
||||
Config.instance().getSettingData().rewardCardAdjLandscape = val;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
});
|
||||
addLabel("Reward/Shop Card Display Ratio");
|
||||
settingGroup.add(rewardCardAdjLandscape).align(Align.right).pad(2);
|
||||
SelectBox tooltipAdjLandscape = Controls.newComboBox(new Float[]{0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 1f, 1.05f, 1.1f, 1.15f, 1.2f, 1.25f, 1.3f, 1.35f, 1.4f, 1.45f, 1.5f, 1.55f, 1.6f}, Config.instance().getSettingData().cardTooltipAdjLandscape, o -> {
|
||||
Float val = (Float) o;
|
||||
if (val == null || val == 0f)
|
||||
val = 1f;
|
||||
Config.instance().getSettingData().cardTooltipAdjLandscape = val;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
});
|
||||
addLabel("Reward/Shop Card Tooltip Ratio");
|
||||
settingGroup.add(tooltipAdjLandscape).align(Align.right).pad(2);
|
||||
} else {
|
||||
//portrait adjustment
|
||||
SelectBox rewardCardAdj = Controls.newComboBox(new Float[]{0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.8f, 1.9f, 2f}, Config.instance().getSettingData().rewardCardAdj, o -> {
|
||||
Float val = (Float) o;
|
||||
if (val == null || val == 0f)
|
||||
val = 1f;
|
||||
Config.instance().getSettingData().rewardCardAdj = val;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
});
|
||||
addLabel("Reward/Shop Card Display Ratio");
|
||||
settingGroup.add(rewardCardAdj).align(Align.right).pad(2);
|
||||
SelectBox tooltipAdj = Controls.newComboBox(new Float[]{0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.8f, 1.9f, 2f}, Config.instance().getSettingData().cardTooltipAdj, o -> {
|
||||
Float val = (Float) o;
|
||||
if (val == null || val == 0f)
|
||||
val = 1f;
|
||||
Config.instance().getSettingData().cardTooltipAdj = val;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
});
|
||||
addLabel("Reward/Shop Card Tooltip Ratio");
|
||||
settingGroup.add(tooltipAdj).align(Align.right).pad(2);
|
||||
}
|
||||
if (!GuiBase.isAndroid()) {
|
||||
addSettingField(Forge.getLocalizer().getMessage("lblFullScreen"), Config.instance().getSettingData().fullScreen, new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@@ -231,12 +265,7 @@ public class SettingsScene extends UIScene {
|
||||
settingGroup.row();
|
||||
back = ui.findActor("return");
|
||||
back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
|
||||
ui.onButtonPress("return", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SettingsScene.this.back();
|
||||
}
|
||||
});
|
||||
ui.onButtonPress("return", () -> SettingsScene.this.back());
|
||||
|
||||
ScrollPane scrollPane = ui.findActor("settings");
|
||||
scrollPane.setActor(settingGroup);
|
||||
|
||||
@@ -3,7 +3,10 @@ package forge.adventure.scene;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import forge.Forge;
|
||||
@@ -18,10 +21,7 @@ import forge.card.ColorSet;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@@ -142,7 +142,7 @@ public class SpellSmithScene extends UIScene {
|
||||
List<CardEdition> editions = StaticData.instance().getSortedEditions();
|
||||
editions = editions.stream().filter(input -> {
|
||||
if(input == null) return false;
|
||||
return(!Config.instance().getConfigData().restrictedEditions.contains(input.getCode()));
|
||||
return(!Arrays.asList(Config.instance().getConfigData().restrictedEditions).contains(input.getCode()));
|
||||
}).collect(Collectors.toList());
|
||||
editionList = ui.findActor("BSelectPlane");
|
||||
rewardDummy = ui.findActor("RewardDummy");
|
||||
|
||||
@@ -7,9 +7,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import forge.Forge;
|
||||
import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.stage.GameStage;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.screens.TransitionScreen;
|
||||
|
||||
@@ -104,6 +106,13 @@ public class StartScene extends UIScene {
|
||||
}
|
||||
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
|
||||
if(Forge.createNewAdventureMap)
|
||||
{
|
||||
this.NewGame();
|
||||
Current.setDebug(true);
|
||||
GameStage.maximumScrollDistance=4f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,19 +3,18 @@ package forge.adventure.stage;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Scaling;
|
||||
import com.badlogic.gdx.utils.viewport.ScalingViewport;
|
||||
import forge.Forge;
|
||||
@@ -42,7 +41,8 @@ public class GameHUD extends Stage {
|
||||
private final Image miniMapPlayer;
|
||||
private final Label lifePoints;
|
||||
private final Label money;
|
||||
private final Image miniMap, gamehud, mapborder, avatarborder, blank;
|
||||
private final Image miniMap,miniMapTooltip, gamehud, mapborder, avatarborder, blank;
|
||||
private Tooltip<Image> toolTip;
|
||||
private TextButton deckActor, menuActor, statsActor, inventoryActor;
|
||||
private UIActor ui;
|
||||
private Touchpad touchpad;
|
||||
@@ -63,6 +63,15 @@ public class GameHUD extends Stage {
|
||||
blank = ui.findActor("blank");
|
||||
miniMap = ui.findActor("map");
|
||||
mapborder = ui.findActor("mapborder");
|
||||
|
||||
miniMapTooltip=new Image();
|
||||
miniMapTooltip.setScaling(Scaling.contain);
|
||||
miniMapTooltip.setSize(miniMap.getWidth()*3,miniMap.getHeight()*3);
|
||||
miniMapTooltip.setPosition(0,0,Align.topLeft);
|
||||
ui.addActor(miniMapTooltip);
|
||||
toolTip=new Tooltip<Image>(miniMapTooltip);
|
||||
toolTip.setInstant(true);
|
||||
mapborder.addListener(toolTip);
|
||||
avatarborder = ui.findActor("avatarborder");
|
||||
deckActor = ui.findActor("deck");
|
||||
deckActor.getLabel().setText(Forge.getLocalizer().getMessage("lblDeck"));
|
||||
@@ -167,6 +176,7 @@ public class GameHUD extends Stage {
|
||||
return true;
|
||||
if(Current.isInDebug())
|
||||
WorldStage.getInstance().GetPlayer().setPosition(x*WorldSave.getCurrentSave().getWorld().getWidthInPixels(),y*WorldSave.getCurrentSave().getWorld().getHeightInPixels());
|
||||
|
||||
return true;
|
||||
}
|
||||
return super.touchDragged(screenX, screenY, pointer);
|
||||
@@ -230,12 +240,21 @@ public class GameHUD extends Stage {
|
||||
}
|
||||
|
||||
Texture miniMapTexture;
|
||||
Texture miniMapToolTipTexture;
|
||||
Pixmap miniMapToolTipPixmap;
|
||||
public void enter() {
|
||||
if(miniMapTexture!=null)
|
||||
miniMapTexture.dispose();
|
||||
miniMapTexture=new Texture(WorldSave.getCurrentSave().getWorld().getBiomeImage());
|
||||
|
||||
if(miniMapToolTipTexture!=null)
|
||||
miniMapToolTipTexture.dispose();
|
||||
if(miniMapToolTipPixmap!=null)
|
||||
miniMapToolTipPixmap.dispose();
|
||||
miniMapToolTipPixmap=new Pixmap((int) (miniMap.getWidth()*3), (int) (miniMap.getHeight()*3), Pixmap.Format.RGBA8888);
|
||||
miniMapToolTipPixmap.drawPixmap(WorldSave.getCurrentSave().getWorld().getBiomeImage(),0,0,WorldSave.getCurrentSave().getWorld().getBiomeImage().getWidth(),WorldSave.getCurrentSave().getWorld().getBiomeImage().getHeight(),0,0,miniMapToolTipPixmap.getWidth(),miniMapToolTipPixmap.getHeight());
|
||||
miniMapToolTipTexture=new Texture(miniMapToolTipPixmap);
|
||||
miniMap.setDrawable(new TextureRegionDrawable(miniMapTexture));
|
||||
miniMapTooltip.setDrawable(new TextureRegionDrawable(miniMapToolTipTexture));
|
||||
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
||||
Deck deck = AdventurePlayer.current().getSelectedDeck();
|
||||
if (deck == null || deck.isEmpty() || deck.getMain().toFlatList().size() < 30) {
|
||||
|
||||
@@ -36,6 +36,8 @@ public abstract class GameStage extends Stage {
|
||||
private float touchY = -1;
|
||||
private final float timer = 0;
|
||||
private float animationTimeout = 0;
|
||||
public static float maximumScrollDistance=1.5f;
|
||||
public static float minimumScrollDistance=0.3f;
|
||||
|
||||
public void startPause(float i) {
|
||||
startPause(i, null);
|
||||
@@ -222,10 +224,10 @@ public abstract class GameStage extends Stage {
|
||||
if (isPaused())
|
||||
return true;
|
||||
camera.zoom += (amountY * 0.03);
|
||||
if (camera.zoom < 0.3f)
|
||||
camera.zoom = 0.3f;
|
||||
if (camera.zoom > 1.5f)
|
||||
camera.zoom = 1.5f;
|
||||
if (camera.zoom < minimumScrollDistance)
|
||||
camera.zoom = minimumScrollDistance;
|
||||
if (camera.zoom > maximumScrollDistance)
|
||||
camera.zoom = maximumScrollDistance;
|
||||
return super.scrolled(amountX, amountY);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import forge.screens.TransitionScreen;
|
||||
import forge.sound.SoundEffectType;
|
||||
import forge.sound.SoundSystem;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -11,11 +11,7 @@ import forge.adventure.character.EnemySprite;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.EnemyData;
|
||||
import forge.adventure.data.WorldData;
|
||||
import forge.adventure.scene.DuelScene;
|
||||
import forge.adventure.scene.RewardScene;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.scene.TileMapScene;
|
||||
import forge.adventure.scene.*;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.SaveFileContent;
|
||||
import forge.adventure.util.SaveFileData;
|
||||
@@ -62,6 +58,8 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
}
|
||||
|
||||
|
||||
final Rectangle tempBoundingRect=new Rectangle();
|
||||
final Vector2 enemyMoveVector =new Vector2();
|
||||
@Override
|
||||
protected void onActing(float delta) {
|
||||
if (player.isMoving()) {
|
||||
@@ -79,7 +77,33 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
continue;
|
||||
}
|
||||
EnemySprite mob=pair.getValue();
|
||||
mob.moveTo(player,delta);
|
||||
|
||||
enemyMoveVector.set(player.getX(), player.getY()).sub(mob.pos());
|
||||
enemyMoveVector.setLength(mob.speed()*delta);
|
||||
tempBoundingRect.set(mob.getX()+ enemyMoveVector.x,mob.getY()+ enemyMoveVector.y,mob.getWidth(),mob.getHeight()*mob.getCollisionHeight());
|
||||
|
||||
if(!mob.getData().flying && WorldSave.getCurrentSave().getWorld().collidingTile(tempBoundingRect))//if direct path is not possible
|
||||
{
|
||||
tempBoundingRect.set(mob.getX()+ enemyMoveVector.x,mob.getY(),mob.getWidth(),mob.getHeight());
|
||||
if(WorldSave.getCurrentSave().getWorld().collidingTile(tempBoundingRect))//if only x path is not possible
|
||||
{
|
||||
tempBoundingRect.set(mob.getX(),mob.getY()+ enemyMoveVector.y,mob.getWidth(),mob.getHeight());
|
||||
if(!WorldSave.getCurrentSave().getWorld().collidingTile(tempBoundingRect))//if y path is possible
|
||||
{
|
||||
mob.moveBy(0, enemyMoveVector.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
mob.moveBy(enemyMoveVector.x, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mob.moveBy(enemyMoveVector.x, enemyMoveVector.y);
|
||||
}
|
||||
|
||||
if (player.collideWith(mob)) {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
@@ -176,19 +200,7 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
public boolean isColliding(Rectangle boundingRect)
|
||||
{
|
||||
|
||||
World world = WorldSave.getCurrentSave().getWorld();
|
||||
int currentBiome = World.highestBiome(world.getBiome((int) boundingRect.getX() / world.getTileSize(), (int) boundingRect.getY() / world.getTileSize()));
|
||||
if(currentBiome==0)
|
||||
return true;
|
||||
currentBiome = World.highestBiome(world.getBiome((int) (boundingRect.getX()+boundingRect.getWidth()) / world.getTileSize(), (int) boundingRect.getY() / world.getTileSize()));
|
||||
if(currentBiome==0)
|
||||
return true;
|
||||
currentBiome = World.highestBiome(world.getBiome((int) (boundingRect.getX()+boundingRect.getWidth())/ world.getTileSize(), (int) (boundingRect.getY()+boundingRect.getHeight()) / world.getTileSize()));
|
||||
if(currentBiome==0)
|
||||
return true;
|
||||
currentBiome = World.highestBiome(world.getBiome((int) boundingRect.getX() / world.getTileSize(), (int) (boundingRect.getY()+boundingRect.getHeight()) / world.getTileSize()));
|
||||
|
||||
return (currentBiome==0);
|
||||
return WorldSave.getCurrentSave().getWorld().collidingTile(boundingRect);
|
||||
}
|
||||
|
||||
private void HandleMonsterSpawn(float delta) {
|
||||
@@ -216,12 +228,25 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
EnemySprite sprite = new EnemySprite(enemyData);
|
||||
float unit = Scene.getIntendedHeight() / 6f;
|
||||
Vector2 spawnPos = new Vector2(1, 1);
|
||||
for(int j=0;j<10;j++)
|
||||
{
|
||||
spawnPos.setLength(unit + (unit * 3) * rand.nextFloat());
|
||||
spawnPos.setAngleDeg(360 * rand.nextFloat());
|
||||
sprite.setX(player.getX() + spawnPos.x);
|
||||
sprite.setY(player.getY() + spawnPos.y);
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
boolean enemyXIsBigger=sprite.getX()>player.getX();
|
||||
boolean enemyYIsBigger=sprite.getY()>player.getY();
|
||||
sprite.setX(player.getX() + spawnPos.x+(i*sprite.getWidth()*(enemyXIsBigger?1:-1)));//maybe find a better way to get spawn points
|
||||
sprite.setY(player.getY() + spawnPos.y+(i*sprite.getHeight()*(enemyYIsBigger?1:-1)));
|
||||
if(sprite.getData().flying || !WorldSave.getCurrentSave().getWorld().collidingTile(sprite.boundingRect()))
|
||||
{
|
||||
enemies.add(Pair.of(globalTimer,sprite));
|
||||
foregroundSprites.addActor(sprite);
|
||||
return;
|
||||
}
|
||||
int g=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,6 +64,18 @@ public class Config {
|
||||
}
|
||||
if(settingsData.videomode == null || settingsData.videomode.isEmpty())
|
||||
settingsData.videomode="720p";
|
||||
//reward card display fine tune
|
||||
if(settingsData.rewardCardAdj == null || settingsData.rewardCardAdj == 0f)
|
||||
settingsData.rewardCardAdj=1f;
|
||||
//tooltip fine tune
|
||||
if(settingsData.cardTooltipAdj == null || settingsData.cardTooltipAdj == 0f)
|
||||
settingsData.cardTooltipAdj=1f;
|
||||
//reward card display fine tune landscape
|
||||
if(settingsData.rewardCardAdjLandscape == null || settingsData.rewardCardAdjLandscape == 0f)
|
||||
settingsData.rewardCardAdjLandscape=1f;
|
||||
//tooltip fine tune landscape
|
||||
if(settingsData.cardTooltipAdjLandscape == null || settingsData.cardTooltipAdjLandscape == 0f)
|
||||
settingsData.cardTooltipAdjLandscape=1f;
|
||||
|
||||
this.plane = settingsData.plane;
|
||||
currentConfig = this;
|
||||
|
||||
@@ -52,6 +52,27 @@ public class Controls {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public SelectBox newComboBox(Float[] text, float item, Function<Object, Void> func) {
|
||||
SelectBox ret = new SelectBox<Float>(GetSkin());
|
||||
ret.getStyle().listStyle.selection.setTopHeight(4);
|
||||
ret.setItems(text);
|
||||
ret.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
try {
|
||||
func.apply(((SelectBox) actor).getSelected());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
func.apply(item);
|
||||
ret.getList().setAlignment(Align.center);
|
||||
ret.setSelected(item);
|
||||
ret.setAlignment(Align.right);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public TextField newTextField(String text) {
|
||||
return new TextField(text, GetSkin());
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ public abstract class DrawOnPixmap {
|
||||
frameBuffer.end();
|
||||
texture.dispose();
|
||||
batch.dispose();
|
||||
if (bigText) //don't know why this is needed to circumvent bug getting default size for the same pixelfont
|
||||
Controls.getBitmapFont("default");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.Forge;
|
||||
import forge.adventure.character.EnemySprite;
|
||||
|
||||
@@ -146,6 +146,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
PaperCard card = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(false));
|
||||
File frontFace = ImageKeys.getImageFile(card.getCardImageKey());
|
||||
if (frontFace != null) {
|
||||
try {
|
||||
if (!Forge.getAssets().manager().contains(frontFace.getPath())) {
|
||||
Forge.getAssets().manager().load(frontFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter());
|
||||
Forge.getAssets().manager().finishLoadingAsset(frontFace.getPath());
|
||||
@@ -157,6 +158,10 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
} else {
|
||||
loaded = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to load image: "+frontFace.getPath());
|
||||
loaded = false;
|
||||
}
|
||||
} else {
|
||||
loaded = false;
|
||||
}
|
||||
@@ -166,11 +171,15 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
PaperCard cardBack = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(true));
|
||||
File backFace = ImageKeys.getImageFile(cardBack.getCardAltImageKey());
|
||||
if (backFace != null) {
|
||||
try {
|
||||
if (!Forge.getAssets().manager().contains(backFace.getPath())) {
|
||||
Forge.getAssets().manager().load(backFace.getPath(), Texture.class, Forge.getAssets().getTextureFilter());
|
||||
Forge.getAssets().manager().finishLoadingAsset(backFace.getPath());
|
||||
ImageCache.updateSynqCount(backFace, 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to load image: "+backFace.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -178,6 +187,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
File lookup = ImageKeys.hasSetLookup(imagePath) ? ImageKeys.setLookUpFile(imagePath, imagePath+"border") : null;
|
||||
int count = 0;
|
||||
if (lookup != null) {
|
||||
try {
|
||||
if (!Forge.getAssets().manager().contains(lookup.getPath())) {
|
||||
Forge.getAssets().manager().load(lookup.getPath(), Texture.class, Forge.getAssets().getTextureFilter());
|
||||
Forge.getAssets().manager().finishLoadingAsset(lookup.getPath());
|
||||
@@ -190,6 +200,10 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
loaded = false;
|
||||
}
|
||||
ImageCache.updateSynqCount(lookup, count);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to load image: "+lookup.getPath());
|
||||
loaded = false;
|
||||
}
|
||||
} else if (!ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false))) {
|
||||
//Cannot find an image file, set up a rendered card until (if) a file is downloaded.
|
||||
T = renderPlaceholder(getGraphics(), reward.getCard()); //Now we can render the card.
|
||||
@@ -361,13 +375,18 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
float fW = x > y ? x : y;
|
||||
float fH = x > y ? y : x;
|
||||
float mul = fW/fH < AR ? AR/(fW/fH) : (fW/fH)/AR;
|
||||
Float custom = Forge.isLandscapeMode() ? Config.instance().getSettingData().cardTooltipAdjLandscape : Config.instance().getSettingData().cardTooltipAdj;
|
||||
if (custom != null && custom != 1f) {
|
||||
mul *= custom;
|
||||
} else {
|
||||
if (fW/fH >= 2f) {//tall display
|
||||
mul = (fW/fH) - ((fW/fH)/AR);
|
||||
if ((fW/fH) >= 2.1f && (fW/fH) < 2.3f)
|
||||
if ((fW/fH) >= 2.1f && (fW/fH) < 2.2f)
|
||||
mul *= 0.9f;
|
||||
else if ((fW/fH) > 2.3) //ultrawide 21:9 Galaxy Fold, Huawei X2, Xperia 1
|
||||
else if ((fW/fH) > 2.2f) //ultrawide 21:9 Galaxy Fold, Huawei X2, Xperia 1
|
||||
mul *= 0.8f;
|
||||
}
|
||||
}
|
||||
if (Forge.isLandscapeMode())
|
||||
drawable.setMinSize(newW*mul, newH);
|
||||
else
|
||||
|
||||
@@ -10,11 +10,7 @@ import com.badlogic.gdx.maps.tiled.TiledMapTile;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMapTileSet;
|
||||
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
|
||||
import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.SerializationException;
|
||||
import com.badlogic.gdx.utils.XmlReader;
|
||||
import com.badlogic.gdx.utils.*;
|
||||
import forge.Forge;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.OrderedMap;
|
||||
@@ -29,7 +28,7 @@ public class UIActor extends Group {
|
||||
setWidth(data.width);
|
||||
setHeight(data.height);
|
||||
|
||||
for (OrderedMap<String, String> element : new Array.ArrayIterator<>(data.elements)) {
|
||||
for (OrderedMap<String, String> element : data.elements) {
|
||||
String type = element.get("type");
|
||||
Actor newActor;
|
||||
if (type == null) {
|
||||
|
||||
154
forge-gui-mobile/src/forge/adventure/world/BiomeStructure.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import forge.adventure.data.BiomeStructureData;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BiomeStructure {
|
||||
|
||||
private BiomeStructureData data;
|
||||
long seed;
|
||||
private int biomeWidth;
|
||||
private int biomeHeight;
|
||||
private int dataMap[][];
|
||||
private boolean collisionMap[][];
|
||||
boolean init=false;
|
||||
private TextureAtlas structureAtlas;
|
||||
public ColorMap image;
|
||||
private final static int MAXIMUM_WAVEFUNCTIONSIZE=50;
|
||||
|
||||
public BiomeStructure(BiomeStructureData data,long seed,int width,int height)
|
||||
{
|
||||
this.data=data;
|
||||
this.seed=seed;
|
||||
this.biomeWidth = width;
|
||||
this.biomeHeight = height;
|
||||
}
|
||||
public TextureAtlas atlas() {
|
||||
if(structureAtlas==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
structureAtlas = Config.instance().getAtlas(data.structureAtlasPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return structureAtlas;
|
||||
}
|
||||
public int structureObjectCount() {
|
||||
return data.mappingInfo.length;
|
||||
}
|
||||
|
||||
public int objectID(int x, int y) {
|
||||
|
||||
if(!init)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
if(x>=dataMap.length||x<0||y<0||y>=dataMap[0].length)
|
||||
return -1;
|
||||
return dataMap[x][y];
|
||||
}
|
||||
|
||||
public void initialize(ColorMap sourceImage,ColorMap maskImage) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
init=true;
|
||||
int targetWidth=(int) (data.width* biomeWidth);
|
||||
int targetHeight=(int) (data.width* biomeWidth);
|
||||
dataMap=new int[targetWidth][ targetHeight];
|
||||
collisionMap=new boolean[targetWidth][ targetHeight];
|
||||
ColorMap finalImage=new ColorMap(targetWidth, targetHeight);
|
||||
HashMap<Integer,Integer> colorIdMap=new HashMap<>();
|
||||
for(int i=0;i<data.mappingInfo.length;i++)
|
||||
{
|
||||
colorIdMap.put(Integer.parseInt(data.mappingInfo[i].color,16),i);
|
||||
}
|
||||
for(int mx=0;mx<targetWidth;mx+=Math.min(targetWidth-mx,MAXIMUM_WAVEFUNCTIONSIZE))
|
||||
{
|
||||
for(int my=0;my<targetWidth;my+=Math.min(targetHeight-my,MAXIMUM_WAVEFUNCTIONSIZE))
|
||||
{
|
||||
OverlappingModel model= new OverlappingModel(sourceImage,data.N,Math.min(targetWidth-mx,MAXIMUM_WAVEFUNCTIONSIZE), Math.min(targetHeight-my,MAXIMUM_WAVEFUNCTIONSIZE),data.periodicInput,data.periodicOutput,data.symmetry,data.ground);
|
||||
|
||||
boolean suc=false;
|
||||
for(int i=0;i<10&&!suc;i++)
|
||||
suc=model.run((int) seed+(i*5355)+mx*my,0);
|
||||
if(!suc)
|
||||
{
|
||||
for(int x=0;x<dataMap.length;x++)
|
||||
for(int y=0;y<dataMap[x].length;y++)
|
||||
dataMap[mx+x][my+y]=-1;
|
||||
return;
|
||||
}
|
||||
image=model.graphics();
|
||||
for(int x=0;x<image.getWidth();x++)
|
||||
{
|
||||
|
||||
for(int y=0;y<image.getHeight();y++)
|
||||
{
|
||||
boolean isWhitePixel=maskImage!=null&&(maskImage.getColor((int) ((mx+x)*maskImage.getWidth()/(float)targetWidth),(int)((my+y)*(maskImage.getHeight()/(float)targetHeight)) )).equals(Color.WHITE);
|
||||
|
||||
if(isWhitePixel)
|
||||
finalImage.setColor(mx+x,my+y, Color.WHITE);
|
||||
else
|
||||
finalImage.setColor(mx+x,my+y, image.getColor(x,y));
|
||||
int rgb=Color.rgb888(image.getColor(x,y)) ;
|
||||
if(isWhitePixel||!colorIdMap.containsKey(rgb))
|
||||
{
|
||||
dataMap[mx+x][my+y]=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataMap[mx+x][my+y]=colorIdMap.get(rgb);
|
||||
collisionMap[mx+x][my+y]=data.mappingInfo[colorIdMap.get(rgb)].collision;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
image=finalImage;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public void initialize() {
|
||||
initialize(sourceImage(),maskImage());
|
||||
}
|
||||
|
||||
public ColorMap sourceImage() {
|
||||
return new ColorMap(Config.instance().getFile(data.sourcePath));
|
||||
}
|
||||
public String sourceImagePath() {
|
||||
return (Config.instance().getFilePath(data.sourcePath));
|
||||
}
|
||||
private ColorMap maskImage() {
|
||||
return new ColorMap(Config.instance().getFile(data.maskPath));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public BiomeStructureData.BiomeStructureDataMapping[] mapping() {
|
||||
return data.mappingInfo;
|
||||
}
|
||||
|
||||
|
||||
public boolean collision(int x, int y) {
|
||||
if(!init)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
if(x>=collisionMap.length||x<0||y<0||y>=collisionMap[0].length)
|
||||
return false;
|
||||
return collisionMap[x][y];
|
||||
}
|
||||
|
||||
public String maskImagePath() {
|
||||
return (Config.instance().getFilePath(data.maskPath));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeStructureData;
|
||||
import forge.adventure.data.BiomeTerrainData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.gui.FThreads;
|
||||
@@ -19,7 +20,7 @@ import java.util.ArrayList;
|
||||
public class BiomeTexture implements Serializable {
|
||||
private final BiomeData data;
|
||||
private final int tileSize;
|
||||
public Pixmap emptyPixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||
public static Pixmap emptyPixmap = null;
|
||||
ArrayList<ArrayList<Pixmap>> images = new ArrayList<>();
|
||||
ArrayList<ArrayList<Pixmap>> smallImages = new ArrayList<>();
|
||||
ArrayList<IntMap<Pixmap>> edgeImages = new ArrayList<>();
|
||||
@@ -45,7 +46,6 @@ public class BiomeTexture implements Serializable {
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Pixmap completePicture = null;
|
||||
|
||||
if (images != null) {
|
||||
for (ArrayList<Pixmap> val : images) {
|
||||
@@ -79,22 +79,49 @@ public class BiomeTexture implements Serializable {
|
||||
edgeImages = new ArrayList<>();
|
||||
|
||||
ArrayList<TextureAtlas.AtlasRegion> regions =new ArrayList<>();
|
||||
ArrayList<TextureAtlas> source =new ArrayList<>();
|
||||
regions.add(Config.instance().getAtlas(data.tilesetAtlas).findRegion(data.tilesetName));
|
||||
source.add(Config.instance().getAtlas(data.tilesetAtlas));
|
||||
if(data.terrain!=null)
|
||||
{
|
||||
for(BiomeTerrainData terrain:data.terrain)
|
||||
{
|
||||
regions.add(Config.instance().getAtlas(data.tilesetAtlas).findRegion(terrain.spriteName));
|
||||
TextureAtlas.AtlasRegion region = Config.instance().getAtlas(data.tilesetAtlas).findRegion(terrain.spriteName);
|
||||
if(region==null)
|
||||
{
|
||||
System.err.print("Can not find sprite "+terrain.spriteName);
|
||||
continue;
|
||||
}
|
||||
regions.add(region);
|
||||
source.add(Config.instance().getAtlas(data.tilesetAtlas));
|
||||
}
|
||||
}
|
||||
if(data.structures!=null)
|
||||
{
|
||||
for(BiomeStructureData structureData:data.structures)
|
||||
{
|
||||
BiomeStructure structure=new BiomeStructure(structureData,0,0,0);
|
||||
TextureAtlas atlas=structure.atlas ();
|
||||
for(BiomeStructureData.BiomeStructureDataMapping mapping:structure.mapping())
|
||||
{
|
||||
TextureAtlas.AtlasRegion region = atlas.findRegion(mapping.name);
|
||||
if(region==null)
|
||||
{
|
||||
System.err.print("Can not find sprite "+mapping.name);
|
||||
continue;
|
||||
}
|
||||
regions.add(region);
|
||||
source.add(atlas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TextureAtlas.AtlasRegion region : regions) {
|
||||
ArrayList<Pixmap> pics = new ArrayList<>();
|
||||
ArrayList<Pixmap> spics = new ArrayList<>();
|
||||
if (completePicture == null) {
|
||||
if(!region.getTexture().getTextureData().isPrepared())
|
||||
region.getTexture().getTextureData().prepare();
|
||||
completePicture = region.getTexture().getTextureData().consumePixmap();
|
||||
}
|
||||
|
||||
Pixmap completePicture = region.getTexture().getTextureData().consumePixmap();
|
||||
for (int y = 0; y < 4; y++) {
|
||||
for (int x = 0; x < 3; x++) {
|
||||
int px = region.getRegionX() + (x * tileSize);
|
||||
@@ -117,6 +144,7 @@ public class BiomeTexture implements Serializable {
|
||||
smallImages.add(spics);
|
||||
edgeImages.add(new IntMap<>());
|
||||
|
||||
completePicture.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -124,6 +152,8 @@ public class BiomeTexture implements Serializable {
|
||||
|
||||
public Pixmap getPixmap(int biomeSubIndex) {
|
||||
if (biomeSubIndex >= edgeImages.size() || biomeSubIndex < 0) {
|
||||
if(emptyPixmap==null)
|
||||
emptyPixmap=new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||
return emptyPixmap;
|
||||
}
|
||||
return images.get(biomeSubIndex).get(BigPictures.Center.value);
|
||||
|
||||
49
forge-gui-mobile/src/forge/adventure/world/ColorMap.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
|
||||
public class ColorMap
|
||||
{
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final Color[] data;
|
||||
public ColorMap(int w,int h)
|
||||
{
|
||||
width=w;
|
||||
height=h;
|
||||
data=new Color[w*h];
|
||||
for(int i=0;i<w*h;i++)
|
||||
data[i]=new Color();
|
||||
}
|
||||
|
||||
public ColorMap(FileHandle file) {
|
||||
Pixmap pdata=new Pixmap(file);
|
||||
width=pdata.getWidth();
|
||||
height=pdata.getHeight();
|
||||
data=new Color[width*height];
|
||||
for(int y=0;y<height;y++)
|
||||
for(int x=0;x<width;x++)
|
||||
{
|
||||
data[x+y*width]=new Color(pdata.getPixel(x,y));
|
||||
}
|
||||
pdata.dispose();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public Color getColor(int x, int y) {
|
||||
return data[x+y*width];
|
||||
}
|
||||
|
||||
public void setColor(int x, int y, Color c) {
|
||||
data[x+y*width].set(c);
|
||||
}
|
||||
}
|
||||
226
forge-gui-mobile/src/forge/adventure/world/Model.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class Model {
|
||||
protected boolean[][] wave;
|
||||
protected int[][][] propagator;
|
||||
int[][][] compatible;
|
||||
protected int[] observed;
|
||||
|
||||
int[] stack;
|
||||
int stacksize;
|
||||
|
||||
protected Random random;
|
||||
protected int FMX, FMY, T;
|
||||
protected boolean periodic;
|
||||
protected Double[] weights;
|
||||
double[] weightLogWeights;
|
||||
|
||||
int[] sumsOfOnes;
|
||||
double sumOfWeights, sumOfWeightLogWeights, startingEntropy;
|
||||
double[] sumsOfWeights, sumsOfWeightLogWeights, entropies;
|
||||
private double[] distribution;
|
||||
|
||||
protected Model(int width, int height) {
|
||||
this.FMX = width;
|
||||
this.FMY = height;
|
||||
}
|
||||
|
||||
protected abstract boolean onBoundary(int x, int y);
|
||||
|
||||
public abstract ColorMap graphics();
|
||||
|
||||
protected static int[] DX = { -1, 0, 1, 0 };
|
||||
protected static int[] DY = { 0, 1, 0, -1 };
|
||||
static int[] oppposite = { 2, 3, 0, 1 };
|
||||
|
||||
static int randomIndice(double[] arr, double r) {
|
||||
double sum = 0;
|
||||
|
||||
for (int j = 0; j < arr.length; j++) sum += arr[j];
|
||||
|
||||
for (int j = 0; j < arr.length; j++) arr[j] /= sum;
|
||||
|
||||
int i = 0;
|
||||
double x = 0;
|
||||
|
||||
while (i < arr.length) {
|
||||
x += arr[i];
|
||||
if (r <= x) return i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long toPower(int a, int n) {
|
||||
long product = 1;
|
||||
for (int i = 0; i < n; i++) product *= a;
|
||||
return product;
|
||||
}
|
||||
|
||||
void init() {
|
||||
this.wave = new boolean[this.FMX * this.FMY][];
|
||||
this.compatible = new int[this.wave.length][][];
|
||||
for (int i = 0; i < wave.length; i++) {
|
||||
this.wave[i] = new boolean[this.T];
|
||||
this.compatible[i] = new int[this.T][];
|
||||
for (int t = 0; t < this.T; t++) this.compatible[i][t] = new int[4];
|
||||
}
|
||||
|
||||
this.weightLogWeights = new double[this.T];
|
||||
this.distribution = new double[this.T];
|
||||
this.sumOfWeights = 0;
|
||||
this.sumOfWeightLogWeights = 0;
|
||||
|
||||
for (int t = 0; t < this.T; t++) {
|
||||
this.weightLogWeights[t] = this.weights[t] * Math.log(this.weights[t]);
|
||||
this.sumOfWeights += this.weights[t];
|
||||
this.sumOfWeightLogWeights += this.weightLogWeights[t];
|
||||
}
|
||||
|
||||
this.startingEntropy =
|
||||
Math.log(this.sumOfWeights) -
|
||||
this.sumOfWeightLogWeights /
|
||||
this.sumOfWeights;
|
||||
|
||||
this.sumsOfOnes = new int[this.FMX * this.FMY];
|
||||
this.sumsOfWeights = new double[this.FMX * this.FMY];
|
||||
this.sumsOfWeightLogWeights = new double[this.FMX * this.FMY];
|
||||
this.entropies = new double[this.FMX * this.FMY];
|
||||
|
||||
this.stack = new int[(this.wave.length * this.T)*2];
|
||||
this.stacksize = 0;
|
||||
}
|
||||
|
||||
Boolean observe() {
|
||||
double min = 1e+3;
|
||||
int argmin = -1;
|
||||
|
||||
for (int i = 0; i < this.wave.length; i++) {
|
||||
if (this.onBoundary(i % this.FMX, i / this.FMX)) continue;
|
||||
|
||||
int amount = this.sumsOfOnes[i];
|
||||
if (amount == 0) return false;
|
||||
|
||||
|
||||
double entropy = this.entropies[i];
|
||||
|
||||
if (amount > 1 && entropy <= min) {
|
||||
double noise = 1e-6 * this.random.nextDouble();
|
||||
if (entropy + noise < min) {
|
||||
min = entropy + noise;
|
||||
argmin = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (argmin == -1) {
|
||||
this.observed = new int[this.FMX * this.FMY];
|
||||
for (int i = 0; i < this.wave.length; i++) for (int t = 0; t <
|
||||
this.T; t++) if (this.wave[i][t]) {
|
||||
this.observed[i] = t;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int t = 0; t < this.T; t++) distribution[t] =
|
||||
this.wave[argmin][t] ? this.weights[t] : 0;
|
||||
|
||||
int r = Model.randomIndice(distribution, this.random.nextDouble());
|
||||
|
||||
|
||||
boolean[] w = this.wave[argmin];
|
||||
for (int t = 0; t < this.T; t++) if (w[t] != (t == r)) this.ban(argmin, t);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void ban(int i, int t) {
|
||||
this.wave[i][t] = false;
|
||||
|
||||
int[] comp = this.compatible[i][t];
|
||||
for (int d = 0; d < 4; d++) comp[d] = 0;
|
||||
this.stack[this.stacksize]=i;
|
||||
this.stack[this.stacksize+1]=t;
|
||||
this.stacksize+=2;
|
||||
|
||||
this.sumsOfOnes[i] -= 1;
|
||||
this.sumsOfWeights[i] -= this.weights[t];
|
||||
this.sumsOfWeightLogWeights[i] -= this.weightLogWeights[t];
|
||||
|
||||
double sum = this.sumsOfWeights[i];
|
||||
this.entropies[i] = Math.log(sum) - this.sumsOfWeightLogWeights[i] / sum;
|
||||
}
|
||||
|
||||
protected void propagate() {
|
||||
while (this.stacksize >= 2) {
|
||||
|
||||
int i1 = this.stack[this.stacksize - 2];
|
||||
int x1 = i1 % this.FMX;
|
||||
int y1 = i1 / this.FMX;
|
||||
int stack2 = this.stack[this.stacksize - 1];
|
||||
this.stacksize-=2;
|
||||
for (int d = 0; d < 4; d++) {
|
||||
int dx = Model.DX[d], dy = Model.DY[d];
|
||||
int x2 = x1 + dx, y2 = y1 + dy;
|
||||
|
||||
if (this.onBoundary(x2, y2)) continue;
|
||||
|
||||
if (x2 < 0) x2 += this.FMX; else if (x2 >= this.FMX) x2 -= this.FMX;
|
||||
if (y2 < 0) y2 += this.FMY; else if (y2 >= this.FMY) y2 -= this.FMY;
|
||||
|
||||
int i2 = x2 + y2 * this.FMX;
|
||||
int[] p = this.propagator[d][stack2];
|
||||
int[][] compat = this.compatible[i2];
|
||||
|
||||
for (int l = 0; l < p.length; l++) {
|
||||
int t2 = p[l];
|
||||
int[] comp = compat[t2];
|
||||
|
||||
comp[d]--;
|
||||
|
||||
if (comp[d] == 0) this.ban(i2, t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean run(int seed, int limit) {
|
||||
if (this.wave == null) this.init();
|
||||
|
||||
this.Clear();
|
||||
this.random = new Random(seed);
|
||||
|
||||
for (int l = 0; l < limit || limit == 0; l++) {
|
||||
Boolean result = this.observe();
|
||||
if (result != null)
|
||||
return (boolean) result;
|
||||
this.propagate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Clear() {
|
||||
for (int i = 0; i < this.wave.length; i++) {
|
||||
for (int t = 0; t < this.T; t++) {
|
||||
this.wave[i][t] = true;
|
||||
for (int d = 0; d < 4; d++) this.compatible[i][t][d] =
|
||||
this.propagator[Model.oppposite[d]][t].length;
|
||||
}
|
||||
|
||||
this.sumsOfOnes[i] = this.weights.length;
|
||||
this.sumsOfWeights[i] = this.sumOfWeights;
|
||||
this.sumsOfWeightLogWeights[i] = this.sumOfWeightLogWeights;
|
||||
this.entropies[i] = this.startingEntropy;
|
||||
}
|
||||
}
|
||||
}
|
||||
293
forge-gui-mobile/src/forge/adventure/world/OverlappingModel.java
Normal file
@@ -0,0 +1,293 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class OverlappingModel extends Model {
|
||||
int N;
|
||||
Integer[][] patterns;
|
||||
int ground;
|
||||
List<Color> colors;
|
||||
|
||||
@FunctionalInterface
|
||||
interface Agrees<One, Two, Three, Four, Five> {
|
||||
public Five apply(One one, Two two, Three three, Four four);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the Overlapping Model
|
||||
* @param data BufferedImage data of source image.
|
||||
* @param N Size of the patterns.
|
||||
* @param width The width of the generation (in pixels).
|
||||
* @param height The height of the generation (in pixels).
|
||||
* @param periodicInput Whether the source image is to be considered as periodic (repeatable).
|
||||
* @param periodicOutput Whether the generation should be periodic (repeatable).
|
||||
* @param symmetry Allowed symmetries from 1 (no symmetry) to 8 (all mirrored / rotated variations).
|
||||
* @param ground Id of the specific pattern to use as the bottom of the generation.
|
||||
*/
|
||||
public OverlappingModel(
|
||||
ColorMap data,
|
||||
int N,
|
||||
int width,
|
||||
int height,
|
||||
boolean periodicInput,
|
||||
boolean periodicOutput,
|
||||
int symmetry,
|
||||
int ground
|
||||
) {
|
||||
super(width, height);
|
||||
this.N = N;
|
||||
this.periodic = periodicOutput;
|
||||
|
||||
|
||||
int SMX = data.getWidth(), SMY = data.getHeight();
|
||||
Integer[][] sample = new Integer[SMX][SMY];
|
||||
|
||||
this.colors = new ArrayList<Color>();
|
||||
|
||||
for (int y = 0; y < SMY; y++) for (int x = 0; x < SMX; x++) {
|
||||
Color color = data.getColor(x, y);
|
||||
if(color==null)
|
||||
break;
|
||||
int i = 0;
|
||||
for (Color c : colors) {
|
||||
if (c.equals(color)) break;
|
||||
i++;
|
||||
}
|
||||
if (i == colors.size()) colors.add(color);
|
||||
sample[x][y] = i;
|
||||
}
|
||||
|
||||
int C = this.colors.size();
|
||||
long W = OverlappingModel.toPower(C, this.N * this.N);
|
||||
|
||||
Function<BiFunction<Integer, Integer, Integer>, Integer[]> pattern =
|
||||
(BiFunction<Integer, Integer, Integer> f) -> {
|
||||
Integer[] result = new Integer[this.N * this.N];
|
||||
for (int y = 0; y < this.N; y++) for (int x = 0; x <
|
||||
this.N; x++) result[x + y * this.N] = f.apply(x, y);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
BiFunction<Integer, Integer, Integer[]> patternFromSample =
|
||||
(Integer x, Integer y) -> pattern.apply(
|
||||
(Integer dx, Integer dy) -> sample[(x + dx) % SMX][(y + dy) % SMY]
|
||||
);
|
||||
|
||||
Function<Integer[], Integer[]> rotate =
|
||||
(Integer[] p) -> pattern.apply(
|
||||
(Integer x, Integer y) -> p[this.N - 1 - y + x * this.N]
|
||||
);
|
||||
|
||||
Function<Integer[], Integer[]> reflect =
|
||||
(Integer[] p) -> pattern.apply(
|
||||
(Integer x, Integer y) -> p[this.N - 1 - x + y * this.N]
|
||||
);
|
||||
|
||||
Function<Integer[], Long> index =
|
||||
(Integer[] p) -> {
|
||||
long result = 0, power = 1;
|
||||
for (int i = 0; i < p.length; i++) {
|
||||
result += p[p.length - 1 - i] * power;
|
||||
power *= C;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
Function<Long, Integer[]> patternFromIndex =
|
||||
(Long ind) -> {
|
||||
long residue = ind, power = W;
|
||||
Integer[] result = new Integer[this.N * this.N];
|
||||
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
power /= C;
|
||||
int count = 0;
|
||||
|
||||
while (residue >= power) {
|
||||
residue -= power;
|
||||
count++;
|
||||
}
|
||||
|
||||
result[i] = count;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
HashMap<Long, Integer> weights = new HashMap<Long, Integer>();
|
||||
List<Long> ordering = new ArrayList<Long>();
|
||||
|
||||
for (int y = 0; y < (periodicInput ? SMY : SMY - N + 1); y++) for (int x =
|
||||
0; x < (periodicInput ? SMX : SMX - this.N + 1); x++) {
|
||||
Integer[][] ps = new Integer[8][];
|
||||
|
||||
ps[0] = patternFromSample.apply(x, y);
|
||||
ps[1] = reflect.apply(ps[0]);
|
||||
ps[2] = rotate.apply(ps[0]);
|
||||
ps[3] = reflect.apply(ps[2]);
|
||||
ps[4] = rotate.apply(ps[2]);
|
||||
ps[5] = reflect.apply(ps[4]);
|
||||
ps[6] = rotate.apply(ps[4]);
|
||||
ps[7] = reflect.apply(ps[6]);
|
||||
|
||||
for (int k = 0; k < symmetry; k++) {
|
||||
long ind = index.apply(ps[k]);
|
||||
if (weights.containsKey(ind)) weights.put(
|
||||
ind,
|
||||
weights.get(ind) + 1
|
||||
); else {
|
||||
weights.put(ind, 1);
|
||||
ordering.add(ind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.T = weights.size();
|
||||
this.ground = (ground + this.T) % this.T;
|
||||
this.patterns = new Integer[this.T][];
|
||||
this.weights = new Double[this.T];
|
||||
|
||||
int counter = 0;
|
||||
|
||||
for (long w : ordering) {
|
||||
this.patterns[counter] = patternFromIndex.apply(w);
|
||||
this.weights[counter] = (double) weights.get(w);
|
||||
// System.out.println(this.weights[counter]);
|
||||
|
||||
// weights[counter] = weights[(int) w];
|
||||
counter++;
|
||||
}
|
||||
|
||||
Agrees<Integer[], Integer[], Integer, Integer, Boolean> agrees =
|
||||
(Integer[] p1, Integer[] p2, Integer dx, Integer dy) -> {
|
||||
int xmin = dx < 0 ? 0 : dx;
|
||||
int xmax = dx < 0 ? dx + N : N;
|
||||
int ymin = dy < 0 ? 0 : dy;
|
||||
int ymax = dy < 0 ? dy + N : N;
|
||||
|
||||
for (int y = ymin; y < ymax; y++) for (int x = xmin; x < xmax; x++) if (
|
||||
p1[x + this.N * y] != p2[x - dx + this.N * (y - dy)]
|
||||
) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
this.propagator = new int[4][][];
|
||||
|
||||
// System.out.println(this.T);
|
||||
|
||||
for (int d = 0; d < 4; d++) {
|
||||
this.propagator[d] = new int[this.T][];
|
||||
for (int t = 0; t < this.T; t++) {
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
for (int t2 = 0; t2 < this.T; t2++) if (
|
||||
agrees.apply(
|
||||
this.patterns[t],
|
||||
this.patterns[t2],
|
||||
Model.DX[d],
|
||||
Model.DY[d]
|
||||
)
|
||||
) list.add(t2);
|
||||
this.propagator[d][t] = new int[list.size()];
|
||||
for (int c = 0; c < list.size(); c++) this.propagator[d][t][c] =
|
||||
list.get(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onBoundary(int x, int y) {
|
||||
return (
|
||||
!this.periodic &&
|
||||
(x + this.N > this.FMX || y + this.N > this.FMY || x < 0 || y < 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new BufferedImage generated by the model.
|
||||
* Requires Run() to have been run.
|
||||
*/
|
||||
@Override
|
||||
public ColorMap graphics() {
|
||||
ColorMap result = new ColorMap(
|
||||
this.FMX,
|
||||
this.FMY
|
||||
);
|
||||
|
||||
if (this.observed != null) {
|
||||
for (int y = 0; y < this.FMY; y++) {
|
||||
int dy = y < this.FMY - this.N + 1 ? 0 : this.N - 1;
|
||||
for (int x = 0; x < this.FMX; x++) {
|
||||
int dx = x < this.FMX - this.N + 1 ? 0 : this.N - 1;
|
||||
Color c =
|
||||
this.colors.get(
|
||||
this.patterns[this.observed[x - dx + (y - dy) * this.FMX]][dx +
|
||||
dy *
|
||||
this.N]
|
||||
);
|
||||
|
||||
result.setColor(x, y, c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < this.wave.length; i++) {
|
||||
float contributors = 0, r = 0, g = 0, b = 0;
|
||||
int x = i % this.FMX, y = i / this.FMX;
|
||||
|
||||
for (int dy = 0; dy < this.N; dy++) for (int dx = 0; dx <
|
||||
this.N; dx++) {
|
||||
int sx = x - dx;
|
||||
if (sx < 0) sx += this.FMX;
|
||||
|
||||
int sy = y - dy;
|
||||
if (sy < 0) sy += this.FMY;
|
||||
|
||||
int s = sx + sy * this.FMX;
|
||||
if (this.onBoundary(sx, sy)) continue;
|
||||
for (int t = 0; t < this.T; t++) if (wave[s][t]) {
|
||||
contributors++;
|
||||
Color color = this.colors.get(this.patterns[t][dx + dy * this.N]);
|
||||
r += color.r;
|
||||
g += color.g;
|
||||
b += color.b;
|
||||
}
|
||||
}
|
||||
|
||||
Color c = new Color(
|
||||
r / contributors,
|
||||
g / contributors,
|
||||
b / contributors,1f
|
||||
);
|
||||
result.setColor(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void Clear() {
|
||||
super.Clear();
|
||||
|
||||
if (this.ground != 0) {
|
||||
for (int x = 0; x < this.FMX; x++) {
|
||||
for (int t = 0; t < this.T; t++) if (t != this.ground) this.ban(
|
||||
x + (this.FMY - 1) * this.FMX,
|
||||
t
|
||||
);
|
||||
|
||||
for (int y = 0; y < this.FMY - 1; y++) this.ban(
|
||||
x + y * this.FMX,
|
||||
this.ground
|
||||
);
|
||||
}
|
||||
|
||||
this.propagate();
|
||||
}
|
||||
}
|
||||
}
|
||||
337
forge-gui-mobile/src/forge/adventure/world/SimpleTiledModel.java
Normal file
@@ -0,0 +1,337 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class SimpleTiledModel extends Model {
|
||||
List<Color[]> tiles;
|
||||
List<String> tilenames;
|
||||
int tilesize;
|
||||
boolean black;
|
||||
|
||||
/**
|
||||
* Create a new instance of a Simple Tiled Model.
|
||||
* @param tilesize Size of the tile images in pixels.
|
||||
* @param tileSymmetries Array of Map of tilenames and their symmetries.
|
||||
* @param neighborData Array of Map of left and right neighbor combinations.
|
||||
* @param subsetData Map of Subset definitions.
|
||||
* @param tileData Map of tile image data indexed by tilename.
|
||||
* @param subsetName Name of the subset in subsetData to use.
|
||||
* @param width Output width in tiles.
|
||||
* @param height Output height in tiles.
|
||||
* @param periodic Should the output generation be tileable.
|
||||
* @param black
|
||||
* @param unique
|
||||
*/
|
||||
public SimpleTiledModel(
|
||||
int tilesize,
|
||||
List<Map<String, String>> tileSymmetries,
|
||||
List<Map<String, String>> neighborData,
|
||||
Map<String, String[]> subsetData,
|
||||
Map<String, ColorMap> tileData,
|
||||
String subsetName,
|
||||
int width,
|
||||
int height,
|
||||
boolean periodic,
|
||||
boolean black,
|
||||
boolean unique
|
||||
) {
|
||||
super(width, height);
|
||||
this.periodic = periodic;
|
||||
this.black = black;
|
||||
this.tilesize = tilesize;
|
||||
|
||||
List<String> subset = null;
|
||||
if (
|
||||
subsetName != null &&
|
||||
subsetData != null &&
|
||||
subsetData.containsKey(subsetName)
|
||||
) {
|
||||
subset = Arrays.asList(subsetData.get(subsetName));
|
||||
}
|
||||
|
||||
|
||||
Function<BiFunction<Integer, Integer, Color>, Color[]> tile =
|
||||
(BiFunction<Integer, Integer, Color> f) -> {
|
||||
Color[] result = new Color[this.tilesize * this.tilesize];
|
||||
for (int y = 0; y < this.tilesize; y++) for (int x = 0; x <
|
||||
this.tilesize; x++) result[x + y * tilesize] = f.apply(x, y);
|
||||
return result;
|
||||
};
|
||||
|
||||
Function<Color[], Color[]> rotate =
|
||||
(Color[] array) -> tile.apply(
|
||||
(Integer x, Integer y) -> array[this.tilesize -
|
||||
1 -
|
||||
y +
|
||||
x *
|
||||
this.tilesize]
|
||||
);
|
||||
|
||||
this.tiles = new ArrayList<Color[]>();
|
||||
this.tilenames = new ArrayList<String>();
|
||||
|
||||
List<Double> tempStationary = new ArrayList<Double>();
|
||||
List<Integer[]> action = new ArrayList<Integer[]>();
|
||||
HashMap<String, Integer> firstOccurrence = new HashMap<String, Integer>();
|
||||
|
||||
for (Map<String, String> xtile : tileSymmetries) {
|
||||
String tilename = xtile.get("name");
|
||||
|
||||
Function<Integer, Integer> a, b;
|
||||
int cardinality;
|
||||
|
||||
String sym = xtile.getOrDefault("symmetry", "X");
|
||||
|
||||
if (subset != null && !subset.contains(tilename)) continue;
|
||||
|
||||
switch (sym) {
|
||||
case "L":
|
||||
cardinality = 4;
|
||||
a = (Integer i) -> (i + 1) % 4;
|
||||
b = (Integer i) -> (i % 2) == 0 ? i + 1 : i - 1;
|
||||
break;
|
||||
case "T":
|
||||
cardinality = 4;
|
||||
a = (Integer i) -> (i + 1) % 4;
|
||||
b = (Integer i) -> (i % 2) == 0 ? i : 4 - i;
|
||||
break;
|
||||
case "I":
|
||||
cardinality = 2;
|
||||
a = (Integer i) -> 1 - i;
|
||||
b = (Integer i) -> i;
|
||||
break;
|
||||
case "\\":
|
||||
cardinality = 2;
|
||||
a = (Integer i) -> 1 - i;
|
||||
b = (Integer i) -> 1 - i;
|
||||
break;
|
||||
default:
|
||||
cardinality = 1;
|
||||
a = (Integer i) -> i;
|
||||
b = (Integer i) -> i;
|
||||
break;
|
||||
}
|
||||
|
||||
this.T = action.size();
|
||||
firstOccurrence.put(tilename, this.T);
|
||||
|
||||
Integer[][] map = new Integer[cardinality][];
|
||||
for (int t = 0; t < cardinality; t++) {
|
||||
map[t] = new Integer[8];
|
||||
|
||||
map[t][0] = t;
|
||||
map[t][1] = a.apply(t);
|
||||
map[t][2] = a.apply(a.apply(t));
|
||||
map[t][3] = a.apply(a.apply(a.apply(t)));
|
||||
map[t][4] = b.apply(t);
|
||||
map[t][5] = b.apply(a.apply(t));
|
||||
map[t][6] = b.apply(a.apply(a.apply(t)));
|
||||
map[t][7] = b.apply(a.apply(a.apply(a.apply(t))));
|
||||
|
||||
for (int s = 0; s < 8; s++) map[t][s] += this.T;
|
||||
|
||||
action.add(map[t]);
|
||||
}
|
||||
|
||||
if (unique) {
|
||||
for (int t = 0; t < cardinality; t++) {
|
||||
ColorMap xtileData = tileData.get(tilename);
|
||||
this.tiles.add(
|
||||
tile.apply(
|
||||
(Integer x, Integer y) -> (xtileData.getColor(x, y))
|
||||
)
|
||||
);
|
||||
this.tilenames.add(String.format("%s %s", tilename, t));
|
||||
}
|
||||
} else {
|
||||
ColorMap xtileData = tileData.get(tilename);
|
||||
this.tiles.add(
|
||||
tile.apply(
|
||||
(Integer x, Integer y) -> (xtileData.getColor(x, y))
|
||||
)
|
||||
);
|
||||
|
||||
this.tilenames.add(String.format("%s 0", tilename));
|
||||
|
||||
for (int t = 1; t < cardinality; t++) {
|
||||
this.tiles.add(rotate.apply(this.tiles.get(this.T + t - 1)));
|
||||
this.tilenames.add(String.format("%s %s", tilename, t));
|
||||
}
|
||||
}
|
||||
|
||||
for (int t = 0; t < cardinality; t++) tempStationary.add(
|
||||
Double.valueOf(xtile.getOrDefault("weight", "1.0"))
|
||||
);
|
||||
}
|
||||
|
||||
this.T = action.size();
|
||||
this.weights = tempStationary.toArray(new Double[0]);
|
||||
|
||||
this.propagator = new int[4][][];
|
||||
boolean[][][] tempPropagator = new boolean[4][][];
|
||||
for (int d = 0; d < 4; d++) {
|
||||
tempPropagator[d] = new boolean[this.T][];
|
||||
this.propagator[d] = new int[this.T][];
|
||||
for (int t = 0; t < this.T; t++) tempPropagator[d][t] =
|
||||
new boolean[this.T];
|
||||
}
|
||||
|
||||
|
||||
for (Map<String, String> xneighbor : neighborData) {
|
||||
|
||||
String[] left = Arrays
|
||||
.stream(xneighbor.get("left").split(" "))
|
||||
.filter(x -> !x.isEmpty())
|
||||
.toArray(String[]::new);
|
||||
|
||||
String[] right = Arrays
|
||||
.stream(xneighbor.get("right").split(" "))
|
||||
.filter(x -> !x.isEmpty())
|
||||
.toArray(String[]::new);
|
||||
|
||||
if (
|
||||
subset != null &&
|
||||
(!subset.contains(left[0]) || !subset.contains(right[0]))
|
||||
) continue;
|
||||
|
||||
|
||||
int L = action.get(firstOccurrence.get(left[0]))[left.length == 1 ? 0
|
||||
: Integer.valueOf(left[1])];
|
||||
int D = action.get(L)[1];
|
||||
|
||||
int R = action.get(firstOccurrence.get(right[0]))[right.length == 1 ? 0
|
||||
: Integer.valueOf(right[1])];
|
||||
int U = action.get(R)[1];
|
||||
|
||||
|
||||
tempPropagator[0][R][L] = true;
|
||||
tempPropagator[0][action.get(R)[6]][action.get(L)[6]] = true;
|
||||
tempPropagator[0][action.get(L)[4]][action.get(R)[4]] = true;
|
||||
tempPropagator[0][action.get(L)[2]][action.get(R)[2]] = true;
|
||||
|
||||
tempPropagator[1][U][D] = true;
|
||||
tempPropagator[1][action.get(D)[6]][action.get(U)[6]] = true;
|
||||
tempPropagator[1][action.get(U)[4]][action.get(D)[4]] = true;
|
||||
tempPropagator[1][action.get(D)[2]][action.get(U)[2]] = true;
|
||||
}
|
||||
|
||||
for (int t2 = 0; t2 < this.T; t2++) for (int t1 = 0; t1 < this.T; t1++) {
|
||||
tempPropagator[2][t2][t1] = tempPropagator[0][t1][t2];
|
||||
tempPropagator[3][t2][t1] = tempPropagator[1][t1][t2];
|
||||
}
|
||||
|
||||
ArrayList<ArrayList<ArrayList<Integer>>> sparsePropagator = new ArrayList<ArrayList<ArrayList<Integer>>>();
|
||||
|
||||
for(int d = 0; d < 4; d++) {
|
||||
sparsePropagator.add(d, new ArrayList<ArrayList<Integer>>());
|
||||
for (int t = 0; t < this.T; t++)
|
||||
sparsePropagator.get(d).add(t, new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
for (int d = 0; d < 4; d++) for (int t1 = 0; t1 < this.T; t1++) {
|
||||
ArrayList<Integer> sp = sparsePropagator.get(d).get(t1);
|
||||
boolean[] tp = tempPropagator[d][t1];
|
||||
|
||||
for (int t2 = 0; t2 < this.T; t2++) {
|
||||
if (tp[t2]) sp.add(t2);
|
||||
}
|
||||
|
||||
|
||||
int ST = sp.size();
|
||||
this.propagator[d][t1] = new int[ST];
|
||||
for (int st = 0; st < ST; st++) this.propagator[d][t1][st] = sp.get(st);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onBoundary(int x, int y) {
|
||||
return !this.periodic && (x < 0 || y < 0 || x >= this.FMX || y >= this.FMY);
|
||||
}
|
||||
|
||||
public String textOutput() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
for (int y = 0; y < this.FMY; y++) {
|
||||
for (int x = 0; x < this.FMX; x++)
|
||||
result.append(String.format("{%s}, ", this.tilenames.get(this.observed[x + y * this.FMX])));
|
||||
result.append("\n");
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorMap graphics() {
|
||||
ColorMap result = new ColorMap(
|
||||
this.FMX * this.tilesize,
|
||||
this.FMY * this.tilesize
|
||||
);
|
||||
|
||||
// System.out.println(this.observed);
|
||||
|
||||
if (this.observed != null) {
|
||||
for (int x = 0; x < this.FMX; x++) for (int y = 0; y < this.FMY; y++) {
|
||||
Color[] tile = this.tiles.get(this.observed[x + y * this.FMX]);
|
||||
for (int yt = 0; yt < this.tilesize; yt++) for (int xt = 0; xt <
|
||||
this.tilesize; xt++) {
|
||||
Color c = tile[xt + yt * this.tilesize];
|
||||
result.setColor(
|
||||
x * this.tilesize + xt,
|
||||
y * this.tilesize + yt,
|
||||
c
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int x = 0; x < this.FMX; x++) for (int y = 0; y < this.FMY; y++) {
|
||||
boolean[] a = this.wave[x + y * this.FMX];
|
||||
int amount = IntStream
|
||||
.range(0, a.length)
|
||||
.map(idx -> a[idx] ? 1 : 0)
|
||||
.sum();
|
||||
|
||||
|
||||
double lambda =
|
||||
1.0 /
|
||||
IntStream
|
||||
.range(0, this.T)
|
||||
.filter(idx -> a[idx])
|
||||
.mapToDouble(idx -> this.weights[idx])
|
||||
.sum();
|
||||
|
||||
for (int yt = 0; yt < this.tilesize; yt++) for (int xt = 0; xt <
|
||||
this.tilesize; xt++) {
|
||||
if (this.black && amount == this.T) result.setColor(
|
||||
x * this.tilesize + xt,
|
||||
y * this.tilesize * yt,
|
||||
Color.BLACK
|
||||
); else {
|
||||
double r = 0, g = 0, b = 0;
|
||||
for (int t = 0; t < this.T; t++) if (a[t]) {
|
||||
Color c = this.tiles.get(t)[xt + yt * this.tilesize];
|
||||
r += c.r * this.weights[t] * lambda;
|
||||
g += c.g * this.weights[t] * lambda;
|
||||
b += c.b * this.weights[t] * lambda;
|
||||
}
|
||||
|
||||
Color newColor = new Color((float) r, (float) g, (float) b,1);
|
||||
result.setColor(
|
||||
x * tilesize + xt,
|
||||
y * tilesize + yt,
|
||||
newColor
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,7 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.BiomeSpriteData;
|
||||
import forge.adventure.data.BiomeTerrainData;
|
||||
import forge.adventure.data.PointOfInterestData;
|
||||
import forge.adventure.data.WorldData;
|
||||
import forge.adventure.data.*;
|
||||
import forge.adventure.pointofintrest.PointOfInterest;
|
||||
import forge.adventure.pointofintrest.PointOfInterestMap;
|
||||
import forge.adventure.scene.Scene;
|
||||
@@ -22,12 +18,12 @@ import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
import forge.adventure.util.SaveFileContent;
|
||||
import forge.adventure.util.SaveFileData;
|
||||
import forge.gui.FThreads;
|
||||
import forge.gui.GuiBase;
|
||||
import forge.util.ThreadUtil;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Class that will create the world from the configuration
|
||||
@@ -37,6 +33,9 @@ public class World implements Disposable, SaveFileContent {
|
||||
private Pixmap biomeImage;
|
||||
private long[][] biomeMap;
|
||||
private int[][] terrainMap;
|
||||
private static final int collisionBit = 0b10000000000000000000000000000000;
|
||||
private static final int isStructureBit = 0b01000000000000000000000000000000;
|
||||
private static final int terrainMask = collisionBit | isStructureBit;
|
||||
private int width;
|
||||
private int height;
|
||||
private SpritesDataMap mapObjectIds;
|
||||
@@ -47,14 +46,33 @@ public class World implements Disposable, SaveFileContent {
|
||||
private boolean worldDataLoaded = false;
|
||||
private Texture globalTexture = null;
|
||||
|
||||
public Random getRandom()
|
||||
{
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
static public int highestBiome(long biome) {
|
||||
return (int) (Math.log(Long.highestOneBit(biome)) / Math.log(2));
|
||||
}
|
||||
|
||||
public boolean collidingTile(Rectangle boundingRect) {
|
||||
|
||||
int xLeft = (int) boundingRect.getX() / getTileSize();
|
||||
int yTop = (int) boundingRect.getY() / getTileSize();
|
||||
int xRight = (int) ((boundingRect.getX() + boundingRect.getWidth()) / getTileSize());
|
||||
int yBottom = (int) ((boundingRect.getY() + boundingRect.getHeight()) / getTileSize());
|
||||
|
||||
if (isColliding(xLeft, yTop))
|
||||
return true;
|
||||
if (isColliding(xLeft, yBottom))
|
||||
return true;
|
||||
if (isColliding(xRight, yBottom))
|
||||
return true;
|
||||
if (isColliding(xRight, yTop))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void loadWorldData() {
|
||||
if (worldDataLoaded)
|
||||
return;
|
||||
@@ -85,6 +103,8 @@ public class World implements Disposable, SaveFileContent {
|
||||
biomeImage = saveFileData.readPixmap("biomeImage");
|
||||
biomeMap = (long[][]) saveFileData.readObject("biomeMap");
|
||||
terrainMap = (int[][]) saveFileData.readObject("terrainMap");
|
||||
|
||||
|
||||
width = saveFileData.readInt("width");
|
||||
height = saveFileData.readInt("height");
|
||||
mapObjectIds = new SpritesDataMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize());
|
||||
@@ -116,6 +136,7 @@ public class World implements Disposable, SaveFileContent {
|
||||
public BiomeSpriteData getObject(int id) {
|
||||
return mapObjectIds.get(id);
|
||||
}
|
||||
|
||||
private class DrawingInformation {
|
||||
|
||||
private int neighbors;
|
||||
@@ -133,12 +154,13 @@ public class World implements Disposable, SaveFileContent {
|
||||
regions.drawPixmapOn(terrain, neighbors, drawingPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
public Pixmap getBiomeSprite(int x, int y) {
|
||||
if (x < 0 || y <= 0 || x >= width || y > height)
|
||||
return new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888);
|
||||
|
||||
long biomeIndex = getBiome(x, y);
|
||||
int terrain = getTerrainIndex(x, y);
|
||||
int biomeTerrain = getTerrainIndex(x, y);
|
||||
Pixmap drawingPixmap = new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888);
|
||||
ArrayList<DrawingInformation> information = new ArrayList<>();
|
||||
for (int i = 0; i < biomeTexture.length; i++) {
|
||||
@@ -148,9 +170,8 @@ public class World implements Disposable, SaveFileContent {
|
||||
BiomeTexture regions = biomeTexture[i];
|
||||
if (x <= 0 || y <= 1 || x >= width - 1 || y >= height)//edge
|
||||
{
|
||||
return regions.getPixmap(terrain);
|
||||
return regions.getPixmap(biomeTerrain);
|
||||
}
|
||||
int biomeTerrain=Math.min(regions.images.size()-1,terrain);
|
||||
|
||||
|
||||
int neighbors = 0b000_000_000;
|
||||
@@ -162,14 +183,13 @@ public class World implements Disposable, SaveFileContent {
|
||||
int otherTerrain = getTerrainIndex(x + nx, y + ny);
|
||||
|
||||
|
||||
if ((otherBiome & 1L << i) != 0 && biomeTerrain <= otherTerrain)
|
||||
if ((otherBiome & 1L << i) != 0 && (biomeTerrain == otherTerrain) | biomeTerrain == 0)
|
||||
neighbors |= (1 << bitIndex);
|
||||
|
||||
bitIndex--;
|
||||
}
|
||||
}
|
||||
if(biomeTerrain!=0&&neighbors!=0b111_111_111)
|
||||
{
|
||||
if (biomeTerrain != 0 && neighbors != 0b111_111_111) {
|
||||
bitIndex = 8;
|
||||
int baseNeighbors = 0;
|
||||
for (int ny = 1; ny > -2; ny--) {
|
||||
@@ -186,8 +206,7 @@ public class World implements Disposable, SaveFileContent {
|
||||
}
|
||||
int lastFullNeighbour = -1;
|
||||
int counter = 0;
|
||||
for(DrawingInformation info:information)
|
||||
{
|
||||
for (DrawingInformation info : information) {
|
||||
if (info.neighbors == 0b111_111_111)
|
||||
lastFullNeighbour = counter;
|
||||
counter++;
|
||||
@@ -196,10 +215,8 @@ public class World implements Disposable, SaveFileContent {
|
||||
counter = 0;
|
||||
if (lastFullNeighbour < 0 && information.size() != 0)
|
||||
information.get(0).neighbors = 0b111_111_111;
|
||||
for(DrawingInformation info:information)
|
||||
{
|
||||
if(counter<lastFullNeighbour)
|
||||
{
|
||||
for (DrawingInformation info : information) {
|
||||
if (counter < lastFullNeighbour) {
|
||||
counter++;
|
||||
continue;
|
||||
}
|
||||
@@ -210,24 +227,71 @@ public class World implements Disposable, SaveFileContent {
|
||||
}
|
||||
|
||||
public int getTerrainIndex(int x, int y) {
|
||||
return terrainMap[x][height - y];
|
||||
try {
|
||||
return terrainMap[x][height - y - 1] & ~terrainMask;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStructure(int x, int y) {
|
||||
try {
|
||||
return (terrainMap[x][height - y - 1] & ~isStructureBit) != 0;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public long getBiome(int x, int y) {
|
||||
try {
|
||||
return biomeMap[x][height - y];
|
||||
return biomeMap[x][height - y - 1];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return biomeMap[biomeMap.length - 1][biomeMap[biomeMap.length - 1].length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isColliding(int x, int y) {
|
||||
try {
|
||||
return (terrainMap[x][height - y - 1] & collisionBit) != 0;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public WorldData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
private void clearTerrain(int x, int y, int size) {
|
||||
|
||||
for (int xclear = -size; xclear < size; xclear++)
|
||||
for (int yclear = -size; yclear < size; yclear++) {
|
||||
try {
|
||||
|
||||
terrainMap[x + xclear][height - 1 - (y + yclear)] = 0;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long measureGenerationTime(String msg, long lastTime) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
System.out.print("\n" + msg + " :\t\t" + ((currentTime - lastTime) / 1000f) + " s");
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public World generateNew(long seed) {
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(true);
|
||||
final long[] currentTime = {System.currentTimeMillis()};
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
loadWorldData();
|
||||
if(seed==0) { seed=random.nextLong(); }
|
||||
|
||||
if (seed == 0) {
|
||||
seed = random.nextLong();
|
||||
}
|
||||
this.seed = seed;
|
||||
random.setSeed(seed);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(seed);
|
||||
@@ -250,10 +314,31 @@ public class World implements Disposable, SaveFileContent {
|
||||
pix.setColor(1, 0, 0, 1);
|
||||
pix.fill();
|
||||
|
||||
int biomeIndex = -1;
|
||||
final int[] biomeIndex = {-1};
|
||||
currentTime[0] = measureGenerationTime("loading data", currentTime[0]);
|
||||
HashMap<BiomeStructureData, BiomeStructure> structureDataMap = new HashMap<>();
|
||||
|
||||
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
if (biome.structures != null) {
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
int biomeHeight = (int) Math.round(biome.height * (double) height);
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
long localSeed = seed;
|
||||
ThreadUtil.getServicePool().submit(() -> {
|
||||
long threadStartTime = System.currentTimeMillis();
|
||||
BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight);
|
||||
structure.initialize();
|
||||
structureDataMap.put(data, structure);
|
||||
measureGenerationTime("wavefunctioncollapse " + data.sourcePath, threadStartTime);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
FThreads.invokeInEdtNowOrLater(() -> {
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
|
||||
biomeIndex++;
|
||||
biomeIndex[0]++;
|
||||
int biomeXStart = (int) Math.round(biome.startPointX * (double) width);
|
||||
int biomeYStart = (int) Math.round(biome.startPointY * (double) height);
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
@@ -261,8 +346,8 @@ public class World implements Disposable, SaveFileContent {
|
||||
|
||||
int beginX = Math.max(biomeXStart - biomeWidth / 2, 0);
|
||||
int beginY = Math.max(biomeYStart - biomeHeight / 2, 0);
|
||||
int endX = Math.min(biomeXStart + biomeWidth, width);
|
||||
int endY = Math.min(biomeYStart + biomeHeight, height);
|
||||
int endX = Math.min(biomeXStart + biomeWidth / 2, width);
|
||||
int endY = Math.min(biomeYStart + biomeHeight / 2, height);
|
||||
if (biome.width == 1.0 && biome.height == 1.0) {
|
||||
beginX = 0;
|
||||
beginY = 0;
|
||||
@@ -286,28 +371,61 @@ public class World implements Disposable, SaveFileContent {
|
||||
color.fromHsv(hsv);
|
||||
pix.setColor(color.r, color.g, color.b, 1);
|
||||
pix.drawPixel(x, y);
|
||||
biomeMap[x][y] |= (1L << biomeIndex);
|
||||
biomeMap[x][y] |= (1L << biomeIndex[0]);
|
||||
int terrainCounter = 1;
|
||||
if(biome.terrain==null)
|
||||
continue;
|
||||
for(BiomeTerrainData terrain:biome.terrain)
|
||||
{
|
||||
terrainMap[x][y] = 0;
|
||||
if (biome.terrain != null) {
|
||||
for (BiomeTerrainData terrain : biome.terrain) {
|
||||
float terrainNoise = ((float) noise.eval(x / (float) width * (noiseZoom * terrain.resolution), y / (float) height * (noiseZoom * terrain.resolution)) + 1) / 2;
|
||||
if(terrainNoise>=terrain.min&&terrainNoise<=terrain.max)
|
||||
{
|
||||
if (terrainNoise >= terrain.min && terrainNoise <= terrain.max) {
|
||||
terrainMap[x][y] = terrainCounter;
|
||||
}
|
||||
terrainCounter++;
|
||||
}
|
||||
}
|
||||
if (biome.collision)
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
if (biome.structures != null) {
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
while (!structureDataMap.containsKey(data)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
BiomeStructure structure = structureDataMap.get(data);
|
||||
int structureXStart = x - (biomeXStart - biomeWidth / 2) - (int) ((data.x * biomeWidth) - (data.width * biomeWidth / 2));
|
||||
int structureYStart = y - (biomeYStart - biomeHeight / 2) - (int) ((data.y * biomeHeight) - (data.height * biomeHeight / 2));
|
||||
|
||||
int structureIndex = structure.objectID(structureXStart, structureYStart);
|
||||
if (structureIndex >= 0) {
|
||||
pix.setColor(data.mappingInfo[structureIndex].getColor());
|
||||
pix.drawPixel(x, y);
|
||||
terrainMap[x][y] = terrainCounter + structureIndex;
|
||||
if (structure.collision(structureXStart, structureYStart))
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
terrainMap[x][y] |= isStructureBit;
|
||||
|
||||
}
|
||||
|
||||
terrainCounter += structure.structureObjectCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("biomes in total", currentTime[0]);
|
||||
|
||||
mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(), data.height / getChunkSize());
|
||||
List<PointOfInterest> towns = new ArrayList<>();
|
||||
List<PointOfInterest> notTowns = new ArrayList<>();
|
||||
List<Rectangle> otherPoints = new ArrayList<>();
|
||||
|
||||
clearTerrain((int) (data.width * data.playerStartPosX), (int) (data.height * data.playerStartPosY), 10);
|
||||
otherPoints.add(new Rectangle(((float) data.width * data.playerStartPosX * (float) data.tileSize) - data.tileSize * 3, ((float) data.height * data.playerStartPosY * data.tileSize) - data.tileSize * 3, data.tileSize * 6, data.tileSize * 6));
|
||||
int biomeIndex2 = -1;
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
@@ -325,8 +443,7 @@ public class World implements Disposable, SaveFileContent {
|
||||
y *= (biome.height * height / 2);
|
||||
y += (height - (biome.startPointY * height));
|
||||
|
||||
if((int)x<0||(int)y<=0||(int)y>=height||(int)x>=width|| biomeIndex2!= highestBiome(getBiome((int)x,(int)y)))
|
||||
{
|
||||
if ((int) x < 0 || (int) y <= 0 || (int) y >= height || (int) x >= width || biomeIndex2 != highestBiome(getBiome((int) x, (int) y))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -340,33 +457,29 @@ public class World implements Disposable, SaveFileContent {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (breakNextLoop)
|
||||
{
|
||||
if (breakNextLoop) {
|
||||
boolean foundSolution = false;
|
||||
boolean noSolution = false;
|
||||
breakNextLoop = false;
|
||||
for(int xi=-1;xi<2&&!foundSolution;xi++)
|
||||
{
|
||||
for(int yi=-1;yi<2&&!foundSolution;yi++)
|
||||
{
|
||||
for (int xi = -1; xi < 2 && !foundSolution; xi++) {
|
||||
for (int yi = -1; yi < 2 && !foundSolution; yi++) {
|
||||
for (Rectangle rect : otherPoints) {
|
||||
if (rect.contains(x + xi * data.tileSize, y + yi * data.tileSize)) {
|
||||
noSolution = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!noSolution)
|
||||
{
|
||||
if (!noSolution) {
|
||||
foundSolution = true;
|
||||
x = x + xi * data.tileSize;
|
||||
y = y + yi * data.tileSize;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!foundSolution)
|
||||
{
|
||||
if(counter==499)
|
||||
{
|
||||
if (!foundSolution) {
|
||||
if (counter == 499) {
|
||||
System.err.print("Can not place POI " + poi.name + "\n");
|
||||
}
|
||||
continue;
|
||||
@@ -374,17 +487,19 @@ public class World implements Disposable, SaveFileContent {
|
||||
}
|
||||
otherPoints.add(new Rectangle(x - data.tileSize * 4, y - data.tileSize * 4, data.tileSize * 8, data.tileSize * 8));
|
||||
PointOfInterest newPoint = new PointOfInterest(poi, new Vector2(x, y), random);
|
||||
|
||||
clearTerrain((int) (x / data.tileSize), (int) (y / data.tileSize), 3);
|
||||
mapPoiIds.add(newPoint);
|
||||
|
||||
|
||||
Color color = biome.GetColor();
|
||||
pix.setColor(color.r, 0.1f, 0.1f, 1);
|
||||
pix.drawRectangle((int) x / data.tileSize - 3, height - (int) y / data.tileSize - 3, 6, 6);
|
||||
pix.fillRectangle((int) x / data.tileSize - 3, height - (int) y / data.tileSize - 3, 6, 6);
|
||||
|
||||
|
||||
if (poi.type != null && poi.type.equals("town")) {
|
||||
towns.add(newPoint);
|
||||
} else {
|
||||
notTowns.add(newPoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -393,82 +508,139 @@ public class World implements Disposable, SaveFileContent {
|
||||
}
|
||||
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("poi placement", currentTime[0]);
|
||||
|
||||
//sort towns
|
||||
List<Pair<PointOfInterest, PointOfInterest>> allSortedTowns = new ArrayList<>();//edge is first 32 bits id of first id and last 32 bits id of second
|
||||
List<Pair<PointOfInterest, PointOfInterest>> allSortedTowns = new ArrayList<>();
|
||||
|
||||
HashSet<Long> usedEdges=new HashSet<>();
|
||||
HashSet<Long> usedEdges = new HashSet<>();//edge is first 32 bits id of first id and last 32 bits id of second
|
||||
for (int i = 0; i < towns.size() - 1; i++) {
|
||||
|
||||
PointOfInterest current = towns.get(i);
|
||||
int smallestIndex = -1;
|
||||
int secondSmallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
for (int j = 0; j < towns.size(); j++) {
|
||||
|
||||
if (i == j || usedEdges.contains((long) i | ((long) j << 32)))
|
||||
continue;
|
||||
float dist = current.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist > data.maxRoadDistance)
|
||||
continue;
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
secondSmallestIndex = smallestIndex;
|
||||
smallestIndex = j;
|
||||
|
||||
}
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
if(smallestDistance>data.maxRoadDistance)
|
||||
continue;
|
||||
usedEdges.add((long) i | ((long) smallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) smallestIndex));
|
||||
allSortedTowns.add(Pair.of(current, towns.get(smallestIndex)));
|
||||
|
||||
if (secondSmallestIndex < 0)
|
||||
continue;
|
||||
usedEdges.add((long) i | ((long) secondSmallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) secondSmallestIndex));
|
||||
//allSortedTowns.add(Pair.of(current, towns.get(secondSmallestIndex)));
|
||||
}
|
||||
List<Pair<PointOfInterest, PointOfInterest>> allPOIPathsToNextTown = new ArrayList<>();
|
||||
for (int i = 0; i < notTowns.size() - 1; i++) {
|
||||
|
||||
PointOfInterest poi = notTowns.get(i);
|
||||
int smallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
for (int j = 0; j < towns.size(); j++) {
|
||||
|
||||
float dist = poi.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
smallestIndex = j;
|
||||
|
||||
}
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
allPOIPathsToNextTown.add(Pair.of(poi, towns.get(smallestIndex)));
|
||||
}
|
||||
biomeIndex[0]++;
|
||||
pix.setColor(1, 1, 1, 1);
|
||||
|
||||
//reset terrain path to the next town
|
||||
for (Pair<PointOfInterest, PointOfInterest> poiToTown : allPOIPathsToNextTown) {
|
||||
|
||||
int startX = (int) poiToTown.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) poiToTown.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).y;
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
while (true) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
if ((terrainMap[startX][height - startY] & collisionBit) != 0)//clear terrain if it has collision
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
pix.drawPixel(startX, height - startY);
|
||||
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
biomeIndex++;
|
||||
pix.setColor(1, 1, 1, 1);
|
||||
for (Pair<PointOfInterest, PointOfInterest> townPair : allSortedTowns) {
|
||||
|
||||
Vector2 currentPoint = townPair.getKey().getTilePosition(data.tileSize);
|
||||
Vector2 endPoint = townPair.getValue().getTilePosition(data.tileSize);
|
||||
for (int x = (int) currentPoint.x - 1; x < currentPoint.x + 2; x++) {
|
||||
for (int y = (int) currentPoint.y - 1; y < currentPoint.y + 2; y++) {
|
||||
int startX = (int) townPair.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) townPair.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) townPair.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) townPair.getValue().getTilePosition(data.tileSize).y;
|
||||
for (int x = startX - 1; x < startX + 2; x++) {
|
||||
for (int y = startY - 1; y < startY + 2; y++) {
|
||||
if (x < 0 || y <= 0 || x >= width || y > height) continue;
|
||||
biomeMap[x][height - y] |= (1L << biomeIndex);
|
||||
biomeMap[x][height - y - 1] |= (1L << biomeIndex[0]);
|
||||
terrainMap[x][height - y - 1] = 0;
|
||||
|
||||
|
||||
pix.drawPixel(x, height - y);
|
||||
}
|
||||
}
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
while (true) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
biomeMap[startX][height - startY] |= (1L << biomeIndex[0]);
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
pix.drawPixel(startX, height - startY);
|
||||
|
||||
while (!currentPoint.equals(endPoint)) {
|
||||
float xDir = endPoint.x - currentPoint.x;
|
||||
float yDir = endPoint.y - currentPoint.y;
|
||||
|
||||
if (xDir == 0) {
|
||||
if (yDir > 0)
|
||||
currentPoint.y++;
|
||||
else
|
||||
currentPoint.y--;
|
||||
} else if (yDir == 0) {
|
||||
if (xDir > 0)
|
||||
currentPoint.x++;
|
||||
else
|
||||
currentPoint.x--;
|
||||
} else if (Math.abs(xDir) > Math.abs(yDir)) {
|
||||
|
||||
if (xDir > 0)
|
||||
currentPoint.x++;
|
||||
else
|
||||
currentPoint.x--;
|
||||
} else {
|
||||
if (yDir > 0)
|
||||
currentPoint.y++;
|
||||
else
|
||||
currentPoint.y--;
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
|
||||
if( (int)currentPoint.x<0|| (int)currentPoint.y<=0|| (int)currentPoint.x>=width|| (int)currentPoint.y>height)continue;
|
||||
biomeMap[(int) currentPoint.x][height - (int) currentPoint.y] |= (1L << biomeIndex);
|
||||
pix.drawPixel((int) currentPoint.x, height - (int) currentPoint.y);
|
||||
}
|
||||
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("roads", currentTime[0]);
|
||||
|
||||
mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize());
|
||||
for (int x = 0; x < width; x++) {
|
||||
@@ -476,6 +648,8 @@ public class World implements Disposable, SaveFileContent {
|
||||
int invertedHeight = height - y - 1;
|
||||
int currentBiome = highestBiome(biomeMap[x][invertedHeight]);
|
||||
if (currentBiome >= data.GetBiomes().size())
|
||||
continue;//roads
|
||||
if (isStructure(x, y))
|
||||
continue;
|
||||
BiomeData biome = data.GetBiomes().get(currentBiome);
|
||||
for (String name : biome.spriteNames) {
|
||||
@@ -491,16 +665,22 @@ public class World implements Disposable, SaveFileContent {
|
||||
} else {
|
||||
key = mapObjectIds.intKey(spriteKey);
|
||||
}
|
||||
mapObjectIds.putPosition(key, new Vector2((float) x * data.tileSize + (random.nextFloat() * data.tileSize), (float) y * data.tileSize + (random.nextFloat() * data.tileSize)));
|
||||
|
||||
mapObjectIds.putPosition(key, new Vector2((((float) x) + .25f + random.nextFloat() / 2) * data.tileSize, (((float) y + .25f) - random.nextFloat() / 2) * data.tileSize));
|
||||
break;//only on sprite per point
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
biomeImage = pix;
|
||||
|
||||
measureGenerationTime("sprites", currentTime[0]);
|
||||
});
|
||||
System.out.print("\nGenerating world took :\t\t" + ((System.currentTimeMillis() - startTime) / 1000f) + " s\n");
|
||||
WorldStage.getInstance().clearCache();
|
||||
ThreadUtil.getServicePool().shutdownNow();
|
||||
ThreadUtil.refreshServicePool();
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(false);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -551,6 +731,7 @@ public class World implements Disposable, SaveFileContent {
|
||||
public PointOfInterest findPointsOfInterest(String name) {
|
||||
return mapPoiIds.findPointsOfInterest(name);
|
||||
}
|
||||
|
||||
public int getChunkSize() {
|
||||
return (Scene.getIntendedWidth() > Scene.getIntendedHeight() ? Scene.getIntendedWidth() : Scene.getIntendedHeight()) / data.tileSize;
|
||||
}
|
||||
|
||||
@@ -35,21 +35,19 @@ public class WorldSave {
|
||||
|
||||
private final SignalList onLoadList = new SignalList();
|
||||
|
||||
public final World getWorld()
|
||||
{
|
||||
public final World getWorld() {
|
||||
return world;
|
||||
}
|
||||
public AdventurePlayer getPlayer()
|
||||
{
|
||||
|
||||
public AdventurePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void onLoad(Runnable run)
|
||||
{
|
||||
public void onLoad(Runnable run) {
|
||||
onLoadList.add(run);
|
||||
}
|
||||
public PointOfInterestChanges getPointOfInterestChanges(String id)
|
||||
{
|
||||
|
||||
public PointOfInterestChanges getPointOfInterestChanges(String id) {
|
||||
if (!pointOfInterestChanges.containsKey(id))
|
||||
pointOfInterestChanges.put(id, new PointOfInterestChanges());
|
||||
return pointOfInterestChanges.get(id);
|
||||
@@ -58,12 +56,13 @@ public class WorldSave {
|
||||
static public boolean load(int currentSlot) {
|
||||
|
||||
String fileName = WorldSave.getSaveFile(currentSlot);
|
||||
if (!new File(fileName).exists())
|
||||
return false;
|
||||
new File(getSaveDir()).mkdirs();
|
||||
try {
|
||||
try (FileInputStream fos = new FileInputStream(fileName);
|
||||
InflaterInputStream inf = new InflaterInputStream(fos);
|
||||
ObjectInputStream oos = new ObjectInputStream(inf))
|
||||
{
|
||||
ObjectInputStream oos = new ObjectInputStream(inf)) {
|
||||
currentSave.header = (WorldSaveHeader) oos.readObject();
|
||||
SaveFileData mainData = (SaveFileData) oos.readObject();
|
||||
currentSave.player.load(mainData.readSubData("player"));
|
||||
@@ -87,9 +86,11 @@ public class WorldSave {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isSafeFile(String name) {
|
||||
return filenameToSlot(name) != INVALID_SAVE_SLOT;
|
||||
}
|
||||
|
||||
static public int filenameToSlot(String name) {
|
||||
if (name.equals("auto_save.sav"))
|
||||
return AUTO_SAVE_SLOT;
|
||||
@@ -131,6 +132,7 @@ public class WorldSave {
|
||||
identity = dp.getColorIdentityforAdventure();
|
||||
} else {
|
||||
starterDeck = isFantasy ? DeckgenUtil.getRandomOrPreconOrThemeDeck("", false, false, false) : Config.instance().starterDecks()[startingColorIdentity];
|
||||
identity = DeckProxy.getColorIdentityforAdventure(starterDeck);
|
||||
}
|
||||
currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex, isFantasy, diff);
|
||||
currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize()));
|
||||
@@ -146,12 +148,15 @@ public class WorldSave {
|
||||
public boolean autoSave() {
|
||||
return save("auto save", AUTO_SAVE_SLOT);
|
||||
}
|
||||
|
||||
public boolean quickSave() {
|
||||
return save("quick save", QUICK_SAVE_SLOT);
|
||||
}
|
||||
|
||||
public boolean quickLoad() {
|
||||
return load(QUICK_SAVE_SLOT);
|
||||
}
|
||||
|
||||
public boolean save(String text, int currentSlot) {
|
||||
header.name = text;
|
||||
|
||||
@@ -161,8 +166,7 @@ public class WorldSave {
|
||||
try {
|
||||
try (FileOutputStream fos = new FileOutputStream(fileName);
|
||||
DeflaterOutputStream def = new DeflaterOutputStream(fos);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(def))
|
||||
{
|
||||
ObjectOutputStream oos = new ObjectOutputStream(def)) {
|
||||
header.saveDate = new Date();
|
||||
oos.writeObject(header);
|
||||
SaveFileData mainData = new SaveFileData();
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Assets implements Disposable {
|
||||
private ObjectMap<String, Texture> tmxMap;
|
||||
private Texture defaultImage, dummy;
|
||||
private TextureParameter textureParameter;
|
||||
private int cGen = 0, cGenVal = 0, cFB = 0, cFBVal = 0, cTM, cTMVal = 0, cSF = 0, cSFVal = 0, cCF = 0, cCFVal = 0, aDF = 0, cDFVal = 0;
|
||||
private int cGen = 0, cGenVal = 0, cFB = 0, cFBVal = 0, cTM = 0, cTMVal = 0, cSF = 0, cSFVal = 0, cCF = 0, cCFVal = 0, aDF = 0, cDFVal = 0;
|
||||
public Assets() {
|
||||
//init titlebg fallback
|
||||
fallback_skins().put(0, new Texture(GuiBase.isAndroid()
|
||||
@@ -55,12 +55,16 @@ public class Assets implements Disposable {
|
||||
}
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (counterFonts != null)
|
||||
for (BitmapFont bitmapFont : counterFonts.values())
|
||||
bitmapFont.dispose();
|
||||
if (generatedCards != null)
|
||||
for (Texture texture : generatedCards.values())
|
||||
texture.dispose();
|
||||
if (fallback_skins != null)
|
||||
for (Texture texture : fallback_skins.values())
|
||||
texture.dispose();
|
||||
if (tmxMap != null)
|
||||
for (Texture texture : tmxMap.values())
|
||||
texture.dispose();
|
||||
if (defaultImage != null)
|
||||
|
||||
@@ -293,11 +293,15 @@ public class ImageCache {
|
||||
}
|
||||
String fileName = file.getPath();
|
||||
//load to assetmanager
|
||||
try {
|
||||
if (!Forge.getAssets().manager().contains(fileName, Texture.class)) {
|
||||
Forge.getAssets().manager().load(fileName, Texture.class, Forge.getAssets().getTextureFilter());
|
||||
Forge.getAssets().manager().finishLoadingAsset(fileName);
|
||||
counter += 1;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to load image: "+fileName);
|
||||
}
|
||||
|
||||
//return loaded assets
|
||||
if (others) {
|
||||
@@ -305,7 +309,7 @@ public class ImageCache {
|
||||
} else {
|
||||
Texture cardTexture = Forge.getAssets().manager().get(fileName, Texture.class, false);
|
||||
//if full bordermasking is enabled, update the border color
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (cardTexture != null && Forge.enableUIMask.equals("Full")) {
|
||||
boolean borderless = isBorderless(imageKey);
|
||||
updateBorders(cardTexture.toString(), borderless ? Pair.of(Color.valueOf("#171717").toString(), false): isCloserToWhite(getpixelColor(cardTexture)));
|
||||
//if borderless, generate new texture from the asset and store
|
||||
@@ -327,6 +331,7 @@ public class ImageCache {
|
||||
syncQ.clear();
|
||||
cardsLoaded.clear();
|
||||
counter = 0;
|
||||
CardRenderer.clearcardArtCache();
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
} finally {
|
||||
|
||||
@@ -323,6 +323,8 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
|
||||
|
||||
@Override
|
||||
public boolean tap(float x, float y, int count) {
|
||||
if (count > 1) //prevent double choice lists or activate handle
|
||||
return false;
|
||||
if (renderedCardContains(x, y)) {
|
||||
ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown
|
||||
@Override
|
||||
|
||||
@@ -67,6 +67,12 @@
|
||||
<version>5.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jetopto1.cling</groupId>
|
||||
<artifactId>cling-core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"invertHeight": true,
|
||||
"collision": true,
|
||||
"name": "ocean",
|
||||
"startPointX": 0.5,
|
||||
"startPointY": 0.5,
|
||||
|
||||
@@ -1,37 +1,145 @@
|
||||
{
|
||||
"startPointX": 0.70,
|
||||
"startPointX": 0.7,
|
||||
"startPointY": 0.78,
|
||||
"name": "black",
|
||||
"noiseWeight": 0.5,
|
||||
"distWeight": 1.5,
|
||||
"tilesetName":"Black",
|
||||
"name": "black",
|
||||
"tilesetAtlas": "world/tilesets/terrain.atlas",
|
||||
"tilesetName": "Black",
|
||||
"terrain": [
|
||||
{
|
||||
"spriteName": "Black_1",
|
||||
"min": 0,
|
||||
"max": 0.2,
|
||||
"resolution": 10
|
||||
},{
|
||||
},
|
||||
{
|
||||
"spriteName": "Black_2",
|
||||
"min": 0.8,
|
||||
"max": 1.0,
|
||||
"max": 1,
|
||||
"resolution": 10
|
||||
}
|
||||
],
|
||||
"width": 0.7,
|
||||
"height": 0.7,
|
||||
"color": "110903",
|
||||
"spriteNames":[ "SwampTree","SwampTree2","DarkGras","Skull","SwampRock","DarkWood","Reed","Waterlily","Shroom","Shroom2"] ,
|
||||
"enemies":[ "Beholder","Big Zombie","Black Wiz1","Black Wiz2","Black Wiz3","Dark Knight","Death Knight","Demon","Ghoul","Ghost","Harpy","Harpy 2","High Vampire","Lich","Rakdos Devil","Skeleton","Skeleton Soldier","Vampire","Zombie","Zombie Lord" ] ,
|
||||
"spriteNames": [
|
||||
"SwampTree",
|
||||
"SwampTree2",
|
||||
"DarkGras",
|
||||
"Skull",
|
||||
"SwampRock",
|
||||
"DarkWood",
|
||||
"Reed",
|
||||
"Waterlily",
|
||||
"Shroom",
|
||||
"Shroom2"
|
||||
],
|
||||
"enemies": [
|
||||
"Beholder",
|
||||
"Big Zombie",
|
||||
"Black Wiz1",
|
||||
"Black Wiz2",
|
||||
"Black Wiz3",
|
||||
"Dark Knight",
|
||||
"Death Knight",
|
||||
"Demon",
|
||||
"Ghoul",
|
||||
"Ghost",
|
||||
"Harpy",
|
||||
"Harpy 2",
|
||||
"High Vampire",
|
||||
"Lich",
|
||||
"Rakdos Devil",
|
||||
"Skeleton",
|
||||
"Skeleton Soldier",
|
||||
"Vampire",
|
||||
"Zombie",
|
||||
"Zombie Lord"
|
||||
],
|
||||
"pointsOfInterest": [
|
||||
"Black Castle",
|
||||
"Swamp Town","Swamp Town2",
|
||||
"Swamp Town",
|
||||
"Swamp Town2",
|
||||
"Zombie Town",
|
||||
"Graveyard", "Graveyard1", "Graveyard2", "Graveyard3", "Graveyard4",
|
||||
"VampireCastle", "VampireCastle1", "VampireCastle2",
|
||||
"EvilGrove", "EvilGrove1", "EvilGrove2", "EvilGrove3", "EvilGrove4",
|
||||
"SkullCaveB", "SkullCaveB1", "SkullCaveB2",
|
||||
"CaveB", "CaveB1", "CaveB2", "CaveB3", "CaveB4", "CaveB5", "CaveB6", "CaveB8", "CaveBA"
|
||||
"Graveyard",
|
||||
"Graveyard1",
|
||||
"Graveyard2",
|
||||
"Graveyard3",
|
||||
"Graveyard4",
|
||||
"VampireCastle",
|
||||
"VampireCastle1",
|
||||
"VampireCastle2",
|
||||
"EvilGrove",
|
||||
"EvilGrove1",
|
||||
"EvilGrove2",
|
||||
"EvilGrove3",
|
||||
"EvilGrove4",
|
||||
"SkullCaveB",
|
||||
"SkullCaveB1",
|
||||
"SkullCaveB2",
|
||||
"CaveB",
|
||||
"CaveB1",
|
||||
"CaveB2",
|
||||
"CaveB3",
|
||||
"CaveB4",
|
||||
"CaveB5",
|
||||
"CaveB6",
|
||||
"CaveB8",
|
||||
"CaveBA"
|
||||
],
|
||||
"structures": [
|
||||
{
|
||||
"N": 2,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/swamp_forest.png",
|
||||
"maskPath": "world/tilesets/ring.png",
|
||||
"height": 0.5,
|
||||
"width": 0.5,
|
||||
"symmetry": 8,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "swamp_forest",
|
||||
"color": "007000",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "swamp_water",
|
||||
"color": "005050",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"N": 2,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/swamp_ruins.png",
|
||||
"maskPath": "world/tilesets/circle.png",
|
||||
"height": 0.20000002,
|
||||
"width": 0.20000002,
|
||||
"symmetry": 1,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "deep_swamp",
|
||||
"color": "002000",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "structure",
|
||||
"color": "505050",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "swamp_forest2",
|
||||
"color": "007000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,38 +1,126 @@
|
||||
{
|
||||
"startPointX": 0.79,
|
||||
"startPointY": 0.43,
|
||||
"name": "blue",
|
||||
"noiseWeight": 0.5,
|
||||
"distWeight": 1.5,
|
||||
"tilesetName":"Blue",
|
||||
"name": "blue",
|
||||
"tilesetAtlas": "world/tilesets/terrain.atlas",
|
||||
"tilesetName": "Blue",
|
||||
"terrain": [
|
||||
{
|
||||
"spriteName": "Blue_1",
|
||||
"min": 0,
|
||||
"max": 0.2,
|
||||
"resolution": 10
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"spriteName": "Blue_2",
|
||||
"min": 0.8,
|
||||
"max": 1.0,
|
||||
"max": 1,
|
||||
"resolution": 10
|
||||
}
|
||||
],
|
||||
"width": 0.7,
|
||||
"height": 0.7,
|
||||
"color": "10a2e0",
|
||||
"spriteNames":["IslandTree" ,"Coral" ,"Shell" ],
|
||||
"enemies":[ "Bird","Djinn","Elemental","Merfolk","Merfolk Avatar","Merfolk Fighter","Merfolk Lord","Merfolk Soldier","Merfolk warrior","Blue Wiz1","Blue Wiz2","Blue Wiz3","Geist","Rogue","Sea Monster","Tarkir Djinn","Doppelganger" ] ,
|
||||
"spriteNames": [
|
||||
"IslandTree",
|
||||
"Coral",
|
||||
"Shell"
|
||||
],
|
||||
"enemies": [
|
||||
"Bird",
|
||||
"Djinn",
|
||||
"Elemental",
|
||||
"Merfolk",
|
||||
"Merfolk Avatar",
|
||||
"Merfolk Fighter",
|
||||
"Merfolk Lord",
|
||||
"Merfolk Soldier",
|
||||
"Merfolk warrior",
|
||||
"Blue Wiz1",
|
||||
"Blue Wiz2",
|
||||
"Blue Wiz3",
|
||||
"Geist",
|
||||
"Rogue",
|
||||
"Sea Monster",
|
||||
"Tarkir Djinn",
|
||||
"Doppelganger"
|
||||
],
|
||||
"pointsOfInterest": [
|
||||
"Blue Castle",
|
||||
"Island Town",
|
||||
"NestU",
|
||||
"MerfolkPool", "MerfolkPool1", "MerfolkPool2", "MerfolkPool3", "MerfolkPool4",
|
||||
"DjinnPalace", "DjinnPalace1",
|
||||
"Factory", "Factory1",
|
||||
"MerfolkPool",
|
||||
"MerfolkPool1",
|
||||
"MerfolkPool2",
|
||||
"MerfolkPool3",
|
||||
"MerfolkPool4",
|
||||
"DjinnPalace",
|
||||
"DjinnPalace1",
|
||||
"Factory",
|
||||
"Factory1",
|
||||
"MageTowerX",
|
||||
"MageTowerU", "MageTowerU1", "MageTowerU2", "MageTowerU3", "MageTowerU4", "MageTowerU5", "MageTowerU6", "MageTowerU7", "MageTowerUD",
|
||||
"CaveU", "CaveU1", "CaveU2", "CaveU3", "CaveU4"
|
||||
"MageTowerU",
|
||||
"MageTowerU1",
|
||||
"MageTowerU2",
|
||||
"MageTowerU3",
|
||||
"MageTowerU4",
|
||||
"MageTowerU5",
|
||||
"MageTowerU6",
|
||||
"MageTowerU7",
|
||||
"MageTowerUD",
|
||||
"CaveU",
|
||||
"CaveU1",
|
||||
"CaveU2",
|
||||
"CaveU3",
|
||||
"CaveU4"
|
||||
],
|
||||
"structures": [
|
||||
{
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/water.png",
|
||||
"maskPath": "world/tilesets/circle.png",
|
||||
"height": 0.20000002,
|
||||
"width": 0.20000002,
|
||||
"symmetry": 8,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "water",
|
||||
"color": "0070a0",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "island_forest",
|
||||
"color": "00a000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/island_forest.png",
|
||||
"maskPath": "world/tilesets/ring.png",
|
||||
"height": 0.5,
|
||||
"width": 0.5,
|
||||
"symmetry": 8,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "water",
|
||||
"color": "0070a0",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "island_forest",
|
||||
"color": "00a000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,36 +1,135 @@
|
||||
{
|
||||
"startPointX": 0.22,
|
||||
"startPointY": 0.43,
|
||||
"name": "green",
|
||||
"noiseWeight": 0.5,
|
||||
"distWeight": 1.5,
|
||||
"tilesetName":"Green",
|
||||
"name": "green",
|
||||
"tilesetAtlas": "world/tilesets/terrain.atlas",
|
||||
"tilesetName": "Green",
|
||||
"terrain": [
|
||||
{
|
||||
"spriteName": "Green_1",
|
||||
"min": 0,
|
||||
"max": 0.2,
|
||||
"resolution": 10
|
||||
},{
|
||||
},
|
||||
{
|
||||
"spriteName": "Green_2",
|
||||
"min": 0.8,
|
||||
"max": 1.0,
|
||||
"max": 1,
|
||||
"resolution": 10
|
||||
}
|
||||
],
|
||||
"width": 0.7,
|
||||
"height": 0.7,
|
||||
"color": "59a650",
|
||||
"spriteNames":[ "WoodTree","WoodTree2","Bush","Stump","Moss","Stone","Flower","Wood"] ,
|
||||
"enemies":[ "Ape","Bear","Centaur","Centaur Warrior","Dino","Eldraine Faerie","Elf","Elf warrior","Elk","Faerie","Giant Spider","Gorgon","Gorgon 2","Green Beast","Green Wiz1","Green Wiz2","Green Wiz3","High Elf","Hydra","Satyr","Snake","Spider","Treefolk","Treefolk Guardian","Viper","Werewolf","Wurm" ] ,
|
||||
"spriteNames": [
|
||||
"WoodTree",
|
||||
"WoodTree2",
|
||||
"Bush",
|
||||
"Stump",
|
||||
"Moss",
|
||||
"Stone",
|
||||
"Flower",
|
||||
"Wood"
|
||||
],
|
||||
"enemies": [
|
||||
"Ape",
|
||||
"Bear",
|
||||
"Centaur",
|
||||
"Centaur Warrior",
|
||||
"Dino",
|
||||
"Eldraine Faerie",
|
||||
"Elf",
|
||||
"Elf warrior",
|
||||
"Elk",
|
||||
"Faerie",
|
||||
"Giant Spider",
|
||||
"Gorgon",
|
||||
"Gorgon 2",
|
||||
"Green Beast",
|
||||
"Green Wiz1",
|
||||
"Green Wiz2",
|
||||
"Green Wiz3",
|
||||
"High Elf",
|
||||
"Hydra",
|
||||
"Satyr",
|
||||
"Snake",
|
||||
"Spider",
|
||||
"Treefolk",
|
||||
"Treefolk Guardian",
|
||||
"Viper",
|
||||
"Werewolf",
|
||||
"Wurm"
|
||||
],
|
||||
"pointsOfInterest": [
|
||||
"Green Castle",
|
||||
"Forest Town",
|
||||
"ElfTown",
|
||||
"WurmPond",
|
||||
"Grove", "Grove1", "Grove2", "Grove3", "Grove4", "Grove5", "Grove6", "Grove7", "Grove8",
|
||||
"CatLairG", "CatLairG1", "CatLairG2",
|
||||
"CaveG", "CaveG1", "CaveG2", "CaveG3", "CaveG4", "CaveG5", "CaveG6", "CaveG8", "CaveG9", "CaveGB"
|
||||
"Grove",
|
||||
"Grove1",
|
||||
"Grove2",
|
||||
"Grove3",
|
||||
"Grove4",
|
||||
"Grove5",
|
||||
"Grove6",
|
||||
"Grove7",
|
||||
"Grove8",
|
||||
"CatLairG",
|
||||
"CatLairG1",
|
||||
"CatLairG2",
|
||||
"CaveG",
|
||||
"CaveG1",
|
||||
"CaveG2",
|
||||
"CaveG3",
|
||||
"CaveG4",
|
||||
"CaveG5",
|
||||
"CaveG6",
|
||||
"CaveG8",
|
||||
"CaveG9",
|
||||
"CaveGB"
|
||||
],
|
||||
"structures": [
|
||||
{
|
||||
"N": 2,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/forest.png",
|
||||
"maskPath": "world/tilesets/circle.png",
|
||||
"height": 0.20000002,
|
||||
"width": 0.20000002,
|
||||
"symmetry": 1,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "forest",
|
||||
"color": "007000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"N": 2,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/lake.png",
|
||||
"maskPath": "world/tilesets/ring.png",
|
||||
"height": 0.5,
|
||||
"width": 0.5,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "lake",
|
||||
"color": "0070a0",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "forest2",
|
||||
"color": "009000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,39 +1,144 @@
|
||||
{
|
||||
"startPointX": 0.31,
|
||||
"startPointY": 0.78,
|
||||
"name": "red",
|
||||
"noiseWeight": 0.5,
|
||||
"distWeight": 1.5,
|
||||
"tilesetName":"Red",
|
||||
"name": "red",
|
||||
"tilesetAtlas": "world/tilesets/terrain.atlas",
|
||||
"tilesetName": "Red",
|
||||
"terrain": [
|
||||
{
|
||||
"spriteName": "Red_1",
|
||||
"min": 0,
|
||||
"max": 0.2,
|
||||
"resolution": 10
|
||||
},{
|
||||
},
|
||||
{
|
||||
"spriteName": "Red_2",
|
||||
"min": 0.8,
|
||||
"max": 1.0,
|
||||
"max": 1,
|
||||
"resolution": 10
|
||||
}
|
||||
],
|
||||
"width": 0.7,
|
||||
"height": 0.7,
|
||||
"color": "b63729",
|
||||
"spriteNames":[ "MountainTree","MountainTree2","MountainRock","LargeMountainRock","Gravel"] ,
|
||||
"enemies":[ "Amonkhet Minotaur","Ashmouth Devil","Axgard Dwarf","Berserker","Boggart","Cyclops","Devil","Dinosaur","Dragon","Dwarf","Efreet","Fire Elemental","Flame Elemental","Goblin","Goblin Chief","Goblin Warrior","Hellhound","Immersturm Demon","Khan","Minotaur","Minotaur Flayer","Red Beast","Red Wiz1","Red Wiz2","Red Wiz3","Shaman","Troll","Vampire Lord","Viashino","Yeti" ] ,
|
||||
"spriteNames": [
|
||||
"MountainTree",
|
||||
"MountainTree2",
|
||||
"MountainRock",
|
||||
"Gravel"
|
||||
],
|
||||
"enemies": [
|
||||
"Amonkhet Minotaur",
|
||||
"Ashmouth Devil",
|
||||
"Axgard Dwarf",
|
||||
"Berserker",
|
||||
"Boggart",
|
||||
"Cyclops",
|
||||
"Devil",
|
||||
"Dinosaur",
|
||||
"Dragon",
|
||||
"Dwarf",
|
||||
"Efreet",
|
||||
"Fire Elemental",
|
||||
"Flame Elemental",
|
||||
"Goblin",
|
||||
"Goblin Chief",
|
||||
"Goblin Warrior",
|
||||
"Hellhound",
|
||||
"Immersturm Demon",
|
||||
"Khan",
|
||||
"Minotaur",
|
||||
"Minotaur Flayer",
|
||||
"Red Beast",
|
||||
"Red Wiz1",
|
||||
"Red Wiz2",
|
||||
"Red Wiz3",
|
||||
"Shaman",
|
||||
"Troll",
|
||||
"Vampire Lord",
|
||||
"Viashino",
|
||||
"Yeti"
|
||||
],
|
||||
"pointsOfInterest": [
|
||||
"Red Castle",
|
||||
"Mountain Town",
|
||||
"YuleTown",
|
||||
"BarbarianCamp", "BarbarianCamp1", "BarbarianCamp2",
|
||||
"Maze", "Maze1", "Maze2", "Maze3",
|
||||
"Fort", "Fort5",
|
||||
"Factory", "Factory2", "Factory3",
|
||||
"SnowAbbey", "SnowAbbey1", "SnowAbbey2",
|
||||
"SkullCaveR", "SkullCaveR1", "SkullCaveR2",
|
||||
"CaveR", "CaveR1", "CaveR2", "CaveR3", "CaveR4", "CaveR5", "CaveR6", "CaveR7", "CaveR8", "CaveR9", "CaveRA", "CaveRB", "CaveRC", "CaveRE", "CaveRG", "CaveRH", "CaveRJ"
|
||||
"BarbarianCamp",
|
||||
"BarbarianCamp1",
|
||||
"BarbarianCamp2",
|
||||
"Maze",
|
||||
"Maze1",
|
||||
"Maze2",
|
||||
"Maze3",
|
||||
"Fort",
|
||||
"Fort5",
|
||||
"Factory",
|
||||
"Factory2",
|
||||
"Factory3",
|
||||
"SnowAbbey",
|
||||
"SnowAbbey1",
|
||||
"SnowAbbey2",
|
||||
"SkullCaveR",
|
||||
"SkullCaveR1",
|
||||
"SkullCaveR2",
|
||||
"CaveR",
|
||||
"CaveR1",
|
||||
"CaveR2",
|
||||
"CaveR3",
|
||||
"CaveR4",
|
||||
"CaveR5",
|
||||
"CaveR6",
|
||||
"CaveR7",
|
||||
"CaveR8",
|
||||
"CaveR9",
|
||||
"CaveRA",
|
||||
"CaveRB",
|
||||
"CaveRC",
|
||||
"CaveRE",
|
||||
"CaveRG",
|
||||
"CaveRH",
|
||||
"CaveRJ"
|
||||
],
|
||||
"structures": [
|
||||
{
|
||||
"N": 2,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/mountain.png",
|
||||
"maskPath": "world/tilesets/ring.png",
|
||||
"height": 0.5,
|
||||
"width": 0.5,
|
||||
"periodicOutput": false,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "mountain",
|
||||
"color": "a07020",
|
||||
"collision": true
|
||||
},
|
||||
{
|
||||
"name": "mountain_forest",
|
||||
"color": "007000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"structureAtlasPath": "world/tilesets/structures.atlas",
|
||||
"sourcePath": "world/tilesets/lava.png",
|
||||
"maskPath": "world/tilesets/circle.png",
|
||||
"height": 0.2,
|
||||
"width": 0.2,
|
||||
"mappingInfo": [
|
||||
{
|
||||
"name": "lava",
|
||||
"color": "ff5000",
|
||||
"collision": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 45 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/circle.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/deep_swamp.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,20 @@
|
||||
|
||||
forest.png
|
||||
size: 96,64
|
||||
format: RGBA8888
|
||||
filter: Nearest,Nearest
|
||||
repeat: none
|
||||
Source
|
||||
rotate: false
|
||||
xy: 0, 0
|
||||
size: 16, 16
|
||||
orig: 0, 0
|
||||
offset: 0, 0
|
||||
index: 0
|
||||
structure_000000
|
||||
rotate: false
|
||||
xy: 48, 0
|
||||
size: 48, 64
|
||||
orig: 0, 0
|
||||
offset: 0, 0
|
||||
index: 0
|
||||
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/forest.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/hole.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/lake.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/lava.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/moon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/moon2.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/moon3.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/moon4.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/mountain.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/plateau.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/ring.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
forge-gui/res/adventure/Shandalar/world/tilesets/ring2.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,60 @@
|
||||
|
||||
structures.png
|
||||
size: 288,384
|
||||
format: RGBA8888
|
||||
filter: Nearest,Nearest
|
||||
repeat: none
|
||||
forest
|
||||
xy: 0, 0
|
||||
size: 48, 64
|
||||
lake
|
||||
xy: 48, 0
|
||||
size: 48, 64
|
||||
forest2
|
||||
xy: 96, 0
|
||||
size: 48, 64
|
||||
swamp_forest
|
||||
xy: 0, 64
|
||||
size: 48, 64
|
||||
swamp_forest2
|
||||
xy: 48, 64
|
||||
size: 48, 64
|
||||
structure
|
||||
xy: 96, 64
|
||||
size: 48, 64
|
||||
swamp_water
|
||||
xy: 144, 64
|
||||
size: 48, 64
|
||||
deep_swamp
|
||||
xy: 192, 64
|
||||
size: 48, 64
|
||||
mountain
|
||||
xy: 0, 128
|
||||
size: 48, 64
|
||||
lava
|
||||
xy: 48, 128
|
||||
size: 48, 64
|
||||
mountain_forest
|
||||
xy: 96, 128
|
||||
size: 48, 64
|
||||
plateau
|
||||
xy: 0, 192
|
||||
size: 48, 64
|
||||
plains_forest
|
||||
xy: 48, 192
|
||||
size: 48, 64
|
||||
water
|
||||
xy: 0, 256
|
||||
size: 48, 64
|
||||
island_forest
|
||||
xy: 48, 256
|
||||
size: 48, 64
|
||||
hole
|
||||
xy: 0, 320
|
||||
size: 48, 64
|
||||
waste_mountain
|
||||
xy: 48, 320
|
||||
size: 48, 64
|
||||
waste_structure
|
||||
xy: 96, 320
|
||||
size: 48, 64
|
||||