mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Merge branch 'adventure' into 'master'
Adventure mode See merge request core-developers/forge!5584
This commit is contained in:
6
.gitlab-ci.yml
Normal file
6
.gitlab-ci.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
deploy:
|
||||
image: maven:3.6-jdk-8
|
||||
script:
|
||||
- 'mvn -U -B clean -P windows-linux install'
|
||||
only:
|
||||
- master
|
||||
BIN
forge-adventure/fallback_skin/bg_splash.png
Normal file
BIN
forge-adventure/fallback_skin/bg_splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 208 KiB |
BIN
forge-adventure/fallback_skin/bg_texture.jpg
Normal file
BIN
forge-adventure/fallback_skin/bg_texture.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
forge-adventure/fallback_skin/font1.ttf
Normal file
BIN
forge-adventure/fallback_skin/font1.ttf
Normal file
Binary file not shown.
BIN
forge-adventure/libs/gdx-backend-lwjgl-natives.jar
Normal file
BIN
forge-adventure/libs/gdx-backend-lwjgl-natives.jar
Normal file
Binary file not shown.
BIN
forge-adventure/libs/gdx-backend-lwjgl-sources.jar
Normal file
BIN
forge-adventure/libs/gdx-backend-lwjgl-sources.jar
Normal file
Binary file not shown.
BIN
forge-adventure/libs/gdx-backend-lwjgl.jar
Normal file
BIN
forge-adventure/libs/gdx-backend-lwjgl.jar
Normal file
Binary file not shown.
BIN
forge-adventure/libs/gdx-freetype-natives.jar
Normal file
BIN
forge-adventure/libs/gdx-freetype-natives.jar
Normal file
Binary file not shown.
BIN
forge-adventure/libs/gdx-natives.jar
Normal file
BIN
forge-adventure/libs/gdx-natives.jar
Normal file
Binary file not shown.
233
forge-adventure/pom.xml
Normal file
233
forge-adventure/pom.xml
Normal file
@@ -0,0 +1,233 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.46-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>forge-adventure</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Forge Adventure</name>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}</directory>
|
||||
<includes>
|
||||
<include>**/*.vert</include>
|
||||
<include>**/*.frag</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.akathist.maven.plugins.launch4j</groupId>
|
||||
<artifactId>launch4j-maven-plugin</artifactId>
|
||||
<version>1.7.25</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>l4j-adv</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>launch4j</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<headerType>gui</headerType>
|
||||
<outfile>${project.build.directory}/forge-adventure.exe</outfile>
|
||||
<jar>${project.build.finalName}-jar-with-dependencies.jar</jar>
|
||||
<dontWrapJar>true</dontWrapJar>
|
||||
<errTitle>forge</errTitle>
|
||||
<icon>src/main/config/forge-adventure.ico</icon>
|
||||
<classPath>
|
||||
<mainClass>forge.adventure.Main</mainClass>
|
||||
<addDependencies>false</addDependencies>
|
||||
<preCp>anything</preCp>
|
||||
</classPath>
|
||||
<jre>
|
||||
<minVersion>1.8.0</minVersion>
|
||||
<maxHeapSize>4096</maxHeapSize>
|
||||
<opts>
|
||||
<opt>-Dfile.encoding=UTF-8</opt>
|
||||
</opts>
|
||||
</jre>
|
||||
<versionInfo>
|
||||
<fileVersion>
|
||||
1.0.0.0
|
||||
</fileVersion>
|
||||
<txtFileVersion>
|
||||
1.0.0.0
|
||||
</txtFileVersion>
|
||||
<fileDescription>Forge</fileDescription>
|
||||
<copyright>Forge</copyright>
|
||||
<productVersion>
|
||||
1.0.0.0
|
||||
</productVersion>
|
||||
<txtProductVersion>
|
||||
1.0.0.0
|
||||
</txtProductVersion>
|
||||
<productName>forge-adventure</productName>
|
||||
<internalName>forge-adventure</internalName>
|
||||
<originalFilename>forge-adventure.exe</originalFilename>
|
||||
</versionInfo>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.google.code.maven-replacer-plugin</groupId>
|
||||
<artifactId>replacer</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>replace</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<basedir>${basedir}/${configSourceDirectory}</basedir>
|
||||
<filesToInclude>forge-adventure.sh, forge-adventure.command</filesToInclude>
|
||||
<outputBasedir>${project.build.directory}</outputBasedir>
|
||||
<outputDir>.</outputDir>
|
||||
<regex>false</regex>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>$project.build.finalName$</token>
|
||||
<value>${project.build.finalName}-jar-with-dependencies.jar</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<attach>false</attach>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>forge.adventure.Main</mainClass>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- this is used for inheritance merges -->
|
||||
<phase>package</phase>
|
||||
<!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.jetopto1</groupId>
|
||||
<artifactId>cling</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx</artifactId>
|
||||
<version>1.10.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx-platform</artifactId>
|
||||
<version>1.10.0</version>
|
||||
<classifier>natives-desktop</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx-freetype</artifactId>
|
||||
<version>1.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx-backend-lwjgl3</artifactId>
|
||||
<version>1.10.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx-freetype-platform</artifactId>
|
||||
<version>1.10.0</version>
|
||||
<classifier>natives-desktop</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-game</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-ai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-gui</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-gui-mobile</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.raeleus.TenPatch</groupId>
|
||||
<artifactId>tenpatch</artifactId>
|
||||
<version>5.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>22.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
<artifactId>forge-gui-mobile</artifactId>
|
||||
<version>1.6.46-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
14
forge-adventure/sentry.properties
Normal file
14
forge-adventure/sentry.properties
Normal file
@@ -0,0 +1,14 @@
|
||||
# ideally this should be using HTTPS, but this is fine for now
|
||||
dsn=http://a0b8dbad9b8a49cfa51bf65d462e8dae@sentry.cardforge.org:9000/2
|
||||
stacktrace.app.packages=forge
|
||||
|
||||
# where to store events if offline or can't reach the above server
|
||||
buffer.dir=sentry-events
|
||||
buffer.size=100
|
||||
|
||||
# allow ample time for graceful shutdown
|
||||
buffer.shutdowntimeout=5000
|
||||
async.shutdowntimeout=5000
|
||||
|
||||
# allow longer messages
|
||||
maxmessagelength=1500
|
||||
15
forge-adventure/shaders/grayscale.frag
Normal file
15
forge-adventure/shaders/grayscale.frag
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoords;
|
||||
uniform sampler2D u_texture;
|
||||
uniform float u_grayness;
|
||||
|
||||
void main() {
|
||||
vec4 c = v_color * texture2D(u_texture, v_texCoords);
|
||||
float grey = dot( c.rgb, vec3(0.22, 0.707, 0.071) );
|
||||
vec3 blendedColor = mix(c.rgb, vec3(grey), u_grayness);
|
||||
gl_FragColor = vec4(blendedColor.rgb, c.a);
|
||||
}
|
||||
14
forge-adventure/shaders/grayscale.vert
Normal file
14
forge-adventure/shaders/grayscale.vert
Normal file
@@ -0,0 +1,14 @@
|
||||
attribute vec4 a_position;
|
||||
attribute vec4 a_color;
|
||||
attribute vec2 a_texCoord0;
|
||||
|
||||
uniform mat4 u_projTrans;
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoords;
|
||||
|
||||
void main() {
|
||||
v_color = a_color;
|
||||
v_texCoords = a_texCoord0;
|
||||
gl_Position = u_projTrans * a_position;
|
||||
}
|
||||
40
forge-adventure/shaders/outline.frag
Normal file
40
forge-adventure/shaders/outline.frag
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
uniform vec2 u_viewportInverse;
|
||||
uniform vec3 u_color;
|
||||
uniform float u_offset;
|
||||
uniform float u_step;
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
#define ALPHA_VALUE_BORDER 0.5
|
||||
|
||||
void main() {
|
||||
vec2 T = v_texCoord.xy;
|
||||
|
||||
float alpha = 0.0;
|
||||
bool allin = true;
|
||||
for( float ix = -u_offset; ix < u_offset; ix += u_step )
|
||||
{
|
||||
for( float iy = -u_offset; iy < u_offset; iy += u_step )
|
||||
{
|
||||
float newAlpha = texture2D(u_texture, T + vec2(ix, iy) * u_viewportInverse).a;
|
||||
allin = allin && newAlpha > ALPHA_VALUE_BORDER;
|
||||
if (newAlpha > ALPHA_VALUE_BORDER && newAlpha >= alpha)
|
||||
{
|
||||
alpha = newAlpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allin)
|
||||
{
|
||||
alpha = 0.0;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(u_color,alpha);
|
||||
}
|
||||
16
forge-adventure/shaders/outline.vert
Normal file
16
forge-adventure/shaders/outline.vert
Normal file
@@ -0,0 +1,16 @@
|
||||
uniform mat4 u_projTrans;
|
||||
|
||||
attribute vec4 a_position;
|
||||
attribute vec2 a_texCoord0;
|
||||
attribute vec4 a_color;
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
uniform vec2 u_viewportInverse;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projTrans * a_position;
|
||||
v_texCoord = a_texCoord0;
|
||||
v_color = a_color;
|
||||
}
|
||||
23
forge-adventure/shaders/underwater.frag
Normal file
23
forge-adventure/shaders/underwater.frag
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifdef GL_ES
|
||||
#define PRECISION mediump
|
||||
precision PRECISION float;
|
||||
precision PRECISION int;
|
||||
#else
|
||||
#define PRECISION
|
||||
#endif
|
||||
|
||||
varying vec2 v_texCoords;
|
||||
uniform sampler2D u_texture;
|
||||
uniform float u_amount;
|
||||
uniform float u_speed;
|
||||
uniform float u_time;
|
||||
|
||||
void main () {
|
||||
vec2 uv = v_texCoords;
|
||||
|
||||
uv.y += (cos((uv.y + (u_time * 0.04 * u_speed)) * 45.0) * 0.0019 * u_amount) + (cos((uv.y + (u_time * 0.1 * u_speed)) * 10.0) * 0.002 * u_amount);
|
||||
|
||||
uv.x += (sin((uv.y + (u_time * 0.07 * u_speed)) * 15.0) * 0.0029 * u_amount) + (sin((uv.y + (u_time * 0.1 * u_speed)) * 15.0) * 0.002 * u_amount);
|
||||
|
||||
gl_FragColor = texture2D(u_texture, uv);
|
||||
}
|
||||
57
forge-adventure/shaders/warp.frag
Normal file
57
forge-adventure/shaders/warp.frag
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
varying vec2 v_texCoords;
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform float u_time;
|
||||
uniform float u_speed;
|
||||
uniform float u_amount;
|
||||
uniform vec2 u_viewport;
|
||||
uniform vec2 u_position;
|
||||
|
||||
float random2d(vec2 n) {
|
||||
return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
|
||||
}
|
||||
|
||||
float randomRange (in vec2 seed, in float min, in float max) {
|
||||
return min + random2d(seed) * (max - min);
|
||||
}
|
||||
|
||||
float insideRange(float v, float bottom, float top) {
|
||||
return step(bottom, v) - step(top, v);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float time = floor(u_time * u_speed * 60.0);
|
||||
|
||||
vec3 outCol = texture2D(u_texture, v_texCoords).rgb;
|
||||
|
||||
float maxOffset = u_amount/2.0;
|
||||
for (float i = 0.0; i < 2.0; i += 1.0) {
|
||||
float sliceY = random2d(vec2(time, 2345.0 + float(i)));
|
||||
float sliceH = random2d(vec2(time, 9035.0 + float(i))) * 0.25;
|
||||
float hOffset = randomRange(vec2(time, 9625.0 + float(i)), -maxOffset, maxOffset);
|
||||
vec2 uvOff = v_texCoords;
|
||||
uvOff.x += hOffset;
|
||||
if (insideRange(v_texCoords.y, sliceY, fract(sliceY+sliceH)) == 1.0){
|
||||
outCol = texture2D(u_texture, uvOff).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
float maxColOffset = u_amount / 6.0;
|
||||
float rnd = random2d(vec2(time , 9545.0));
|
||||
vec2 colOffset = vec2(randomRange(vec2(time , 9545.0), -maxColOffset, maxColOffset),
|
||||
randomRange(vec2(time , 7205.0), -maxColOffset, maxColOffset));
|
||||
if (rnd < 0.33) {
|
||||
outCol.r = texture2D(u_texture, v_texCoords + colOffset).r;
|
||||
} else if (rnd < 0.66) {
|
||||
outCol.g = texture2D(u_texture, v_texCoords + colOffset).g;
|
||||
} else {
|
||||
outCol.b = texture2D(u_texture, v_texCoords + colOffset).b;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(outCol, 1.0);
|
||||
}
|
||||
3
forge-adventure/src/main/config/forge-adventure.command
Normal file
3
forge-adventure/src/main/config/forge-adventure.command
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
cd $(dirname "${0}")
|
||||
java -Xmx4096m -Dfile.encoding=UTF-8 -jar $project.build.finalName$
|
||||
BIN
forge-adventure/src/main/config/forge-adventure.ico
Normal file
BIN
forge-adventure/src/main/config/forge-adventure.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
3
forge-adventure/src/main/config/forge-adventure.sh
Normal file
3
forge-adventure/src/main/config/forge-adventure.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
cd $(dirname "${0}")
|
||||
java -Xmx4096m -Dfile.encoding=UTF-8 -jar $project.build.finalName$
|
||||
BIN
forge-adventure/src/main/config/forge.ico
Normal file
BIN
forge-adventure/src/main/config/forge.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 222 KiB |
@@ -0,0 +1,195 @@
|
||||
package forge.adventure;
|
||||
|
||||
import com.badlogic.gdx.ApplicationAdapter;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ScreenUtils;
|
||||
import forge.Graphics;
|
||||
import forge.adventure.scene.ForgeScene;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
/**
|
||||
* Application adapter the handle switching and fading between scenes
|
||||
*/
|
||||
public class AdventureApplicationAdapter extends ApplicationAdapter {
|
||||
public static AdventureApplicationAdapter instance;
|
||||
Scene currentScene = null;
|
||||
Array<Scene> lastScene = new Array<>();
|
||||
private int currentWidth;
|
||||
private int currentHeight;
|
||||
private float animationTimeout;
|
||||
Batch animationBatch;
|
||||
Texture transitionTexture;
|
||||
TextureRegion lastScreenTexture;
|
||||
private boolean sceneWasSwapped =false;
|
||||
private Graphics graphics;
|
||||
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
if(graphics==null)
|
||||
graphics=new Graphics();
|
||||
return graphics;
|
||||
}
|
||||
|
||||
public TextureRegion getLastScreenTexture() {
|
||||
return lastScreenTexture;
|
||||
}
|
||||
public AdventureApplicationAdapter() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public int getCurrentWidth() {
|
||||
return currentWidth;
|
||||
}
|
||||
|
||||
public int getCurrentHeight() {
|
||||
return currentHeight;
|
||||
}
|
||||
|
||||
|
||||
public Scene getCurrentScene() {
|
||||
return currentScene;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int w, int h) {
|
||||
currentWidth = w;
|
||||
currentHeight = h;
|
||||
StartAdventure.app.resize(w, h);
|
||||
super.resize(w, h);
|
||||
}
|
||||
|
||||
public boolean switchScene(Scene newScene) {
|
||||
|
||||
if (currentScene != null) {
|
||||
if (!currentScene.leave())
|
||||
return false;
|
||||
lastScene.add(currentScene);
|
||||
}
|
||||
storeScreen();
|
||||
sceneWasSwapped =true;
|
||||
currentScene = newScene;
|
||||
currentScene.enter();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void storeScreen() {
|
||||
if(!(currentScene instanceof ForgeScene))
|
||||
lastScreenTexture = ScreenUtils.getFrameBufferTexture();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void resLoaded() {
|
||||
for (forge.adventure.scene.SceneType entry : SceneType.values()) {
|
||||
entry.instance.resLoaded();
|
||||
}
|
||||
//AdventureApplicationAdapter.CurrentAdapter.switchScene(SceneType.RewardScene.instance);
|
||||
|
||||
|
||||
switchScene(SceneType.StartScene.instance);
|
||||
animationBatch=new SpriteBatch();
|
||||
transitionTexture =new Texture(Config.instance().getFile("ui/transition.png"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
Pixmap pm = new Pixmap(Config.instance().getFile("skin/cursor.png"));
|
||||
Gdx.graphics.setCursor(Gdx.graphics.newCursor(pm, 0, 0));
|
||||
pm.dispose();
|
||||
for (forge.adventure.scene.SceneType entry : SceneType.values()) {
|
||||
entry.instance.create();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
float delta=Gdx.graphics.getDeltaTime();
|
||||
float transitionTime = 0.2f;
|
||||
if(sceneWasSwapped)
|
||||
{
|
||||
sceneWasSwapped =false;
|
||||
animationTimeout= transitionTime;
|
||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
return;
|
||||
}
|
||||
if(animationTimeout>=0)
|
||||
{
|
||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
animationBatch.begin();
|
||||
animationTimeout-=delta;
|
||||
animationBatch.setColor(1,1,1,1);
|
||||
animationBatch.draw(lastScreenTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.setColor(1,1,1,1-(1/ transitionTime)*animationTimeout);
|
||||
animationBatch.draw(transitionTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.draw(transitionTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.end();
|
||||
if(animationTimeout<0)
|
||||
{
|
||||
currentScene.render();
|
||||
storeScreen();
|
||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(animationTimeout>=-transitionTime)
|
||||
{
|
||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
animationBatch.begin();
|
||||
animationTimeout-=delta;
|
||||
animationBatch.setColor(1,1,1,1);
|
||||
animationBatch.draw(lastScreenTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.setColor(1,1,1,(1/ transitionTime)*(animationTimeout+ transitionTime));
|
||||
animationBatch.draw(transitionTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.draw(transitionTexture,0,0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
|
||||
animationBatch.end();
|
||||
return;
|
||||
}
|
||||
currentScene.render();
|
||||
currentScene.act(delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (forge.adventure.scene.SceneType entry : SceneType.values()) {
|
||||
entry.instance.dispose();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private Scene getLastScene() {
|
||||
return lastScene.size==0?null: lastScene.get(lastScene.size-1);
|
||||
}
|
||||
|
||||
public Scene switchToLast() {
|
||||
|
||||
if(lastScene.size!=0)
|
||||
{
|
||||
storeScreen();
|
||||
currentScene = lastScene.get(lastScene.size-1);
|
||||
currentScene.enter();
|
||||
sceneWasSwapped =true;
|
||||
lastScene.removeIndex(lastScene.size-1);
|
||||
return currentScene;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package forge.adventure;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import forge.interfaces.IDeviceAdapter;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.OperatingSystem;
|
||||
import forge.util.RestartUtil;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Adapter for desktop usage
|
||||
*/
|
||||
public class DesktopAdapter implements IDeviceAdapter {
|
||||
private final String switchOrientationFile;
|
||||
|
||||
public DesktopAdapter(String switchOrientationFile0) {
|
||||
switchOrientationFile = switchOrientationFile0;
|
||||
}
|
||||
|
||||
//just assume desktop always connected to wifi
|
||||
@Override
|
||||
public boolean isConnectedToInternet() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectedToWifi() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadsDir() {
|
||||
return System.getProperty("user.home") + "/Downloads/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean openFile(String filename) {
|
||||
try {
|
||||
Desktop.getDesktop().open(new File(filename));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restart() {
|
||||
if (RestartUtil.prepareForRestart()) {
|
||||
Gdx.app.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
Gdx.app.exit(); //can just use Gdx.app.exit for desktop
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTablet() {
|
||||
return true; //treat desktop the same as a tablet
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLandscapeMode(boolean landscapeMode) {
|
||||
//create file to indicate that landscape mode should be used
|
||||
if (landscapeMode) {
|
||||
FileUtil.writeFile(switchOrientationFile, "1");
|
||||
} else {
|
||||
FileUtil.deleteFile(switchOrientationFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preventSystemSleep(boolean preventSleep) {
|
||||
OperatingSystem.preventSystemSleep(preventSleep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJPEG(InputStream input, OutputStream output) throws IOException {
|
||||
BufferedImage image = ImageIO.read(input);
|
||||
ImageIO.write(image, "jpg", output);
|
||||
}
|
||||
}
|
||||
300
forge-adventure/src/main/java/forge/adventure/Main.java
Normal file
300
forge-adventure/src/main/java/forge/adventure/Main.java
Normal file
@@ -0,0 +1,300 @@
|
||||
package forge.adventure;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
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.graphics.GL20;
|
||||
import com.badlogic.gdx.utils.Clipboard;
|
||||
import forge.Forge;
|
||||
import forge.FrameRate;
|
||||
import forge.GuiMobile;
|
||||
import forge.adventure.scene.SettingsScene;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.assets.AssetsDownloader;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.ImageCache;
|
||||
import forge.error.ExceptionHandler;
|
||||
import forge.gui.FThreads;
|
||||
import forge.gui.GuiBase;
|
||||
import forge.interfaces.IDeviceAdapter;
|
||||
import forge.localinstance.properties.ForgeConstants;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.FScreen;
|
||||
import forge.screens.SplashScreen;
|
||||
import forge.sound.MusicPlaylist;
|
||||
import forge.sound.SoundSystem;
|
||||
import forge.util.BuildInfo;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.FileUtil;
|
||||
import forge.util.Localizer;
|
||||
import io.sentry.Sentry;
|
||||
import io.sentry.SentryClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper to start forge first (splash screen and resources loading)
|
||||
*
|
||||
*/
|
||||
class StartAdventure extends AdventureApplicationAdapter {
|
||||
private static final int continuousRenderingCount = 1; //initialize to 1 since continuous rendering is the default
|
||||
private static final Deque<FScreen> Dscreens = new ArrayDeque<>();
|
||||
private static final boolean isloadingaMatch = false;
|
||||
public static String extrawide = "default";
|
||||
public static float heigtModifier = 0.0f;
|
||||
public static boolean showFPS = false;
|
||||
public static boolean altPlayerLayout = false;
|
||||
public static boolean altZoneTabs = false;
|
||||
public static String enableUIMask = "Crop";
|
||||
public static boolean enablePreloadExtendedArt = false;
|
||||
public static boolean isTabletDevice = false;
|
||||
public static String locale = "en-US";
|
||||
public static boolean hdbuttons = false;
|
||||
public static boolean hdstart = false;
|
||||
public static boolean isPortraitMode = false;
|
||||
public static boolean gameInProgress = false;
|
||||
public static boolean disposeTextures = false;
|
||||
public static int cacheSize = 400;
|
||||
public static int totalDeviceRAM = 0;
|
||||
public static int androidVersion = 0;
|
||||
public static boolean autoCache = false;
|
||||
public static int lastButtonIndex = 0;
|
||||
public static String CJK_Font = "";
|
||||
public static Forge app;
|
||||
private static Clipboard clipboard;
|
||||
private static IDeviceAdapter deviceAdapter;
|
||||
private static FrameRate frameRate;
|
||||
private static FScreen currentScreen;
|
||||
private static SplashScreen splashScreen;
|
||||
private static Forge.KeyInputAdapter keyInputAdapter;
|
||||
private static boolean exited;
|
||||
private static boolean textureFiltering = false;
|
||||
private static boolean destroyThis = false;
|
||||
|
||||
public StartAdventure() {
|
||||
|
||||
super();
|
||||
Forge.isTabletDevice = true;
|
||||
Forge.isPortraitMode = false;
|
||||
Forge.hdbuttons = true;
|
||||
Forge.hdstart = true;
|
||||
|
||||
String path= Files.exists(Paths.get("./res"))?"./":"../forge-gui/";
|
||||
|
||||
app = (Forge) Forge.getApp(new Lwjgl3Clipboard(), new DesktopAdapter(""), path, true, false, 0, true, 0, "", "");
|
||||
|
||||
clipboard = new Lwjgl3Clipboard();
|
||||
GuiBase.setUsingAppDirectory(false); //obb directory on android uses the package name as entrypoint
|
||||
GuiBase.setInterface(new GuiMobile(path));
|
||||
GuiBase.enablePropertyConfig(true);
|
||||
isPortraitMode = true;
|
||||
totalDeviceRAM = 0;
|
||||
GuiBase.setDeviceInfo("", "", 0, 0);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
if (splashScreen != null) {
|
||||
Gdx.gl.glClearColor(1, 0, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear the screen.
|
||||
getGraphics().begin(getCurrentWidth(), getCurrentHeight());
|
||||
splashScreen.setSize(getCurrentWidth(), getCurrentHeight());
|
||||
splashScreen.screenPos.setSize(getCurrentWidth(), getCurrentHeight());
|
||||
if (splashScreen.getRotate180()) {
|
||||
getGraphics().startRotateTransform(getCurrentWidth() / 2f, getCurrentHeight() / 2f, 180);
|
||||
}
|
||||
splashScreen.draw(getGraphics());
|
||||
if (splashScreen.getRotate180()) {
|
||||
getGraphics().endTransform();
|
||||
}
|
||||
|
||||
getGraphics().end();
|
||||
} else {
|
||||
super.render();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
super.resize(width, height);
|
||||
if (splashScreen != null)
|
||||
splashScreen.setSize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
//install our error handler
|
||||
ExceptionHandler.registerErrorHandling();
|
||||
splashScreen = new SplashScreen();
|
||||
frameRate = new FrameRate();
|
||||
/*
|
||||
Set CatchBackKey here and exit the app when you hit the
|
||||
back button while the textures,fonts,etc are still loading,
|
||||
to prevent rendering issue when you try to restart
|
||||
the app again (seems it doesnt dispose correctly...?!?)
|
||||
*/
|
||||
Gdx.input.setCatchKey(Input.Keys.BACK, true);
|
||||
destroyThis = true; //Prevent back()
|
||||
ForgePreferences prefs = SettingsScene.Preference = new ForgePreferences();
|
||||
|
||||
|
||||
String skinName;
|
||||
if (FileUtil.doesFileExist(ForgeConstants.MAIN_PREFS_FILE)) {
|
||||
skinName = prefs.getPref(ForgePreferences.FPref.UI_SKIN);
|
||||
} else {
|
||||
skinName = "default"; //use default skin if preferences file doesn't exist yet
|
||||
}
|
||||
FSkin.loadLight(skinName, splashScreen,Config.instance().getFile("skin"));
|
||||
|
||||
textureFiltering = prefs.getPrefBoolean(ForgePreferences.FPref.UI_LIBGDX_TEXTURE_FILTERING);
|
||||
showFPS = prefs.getPrefBoolean(ForgePreferences.FPref.UI_SHOW_FPS);
|
||||
altPlayerLayout = prefs.getPrefBoolean(ForgePreferences.FPref.UI_ALT_PLAYERINFOLAYOUT);
|
||||
altZoneTabs = prefs.getPrefBoolean(ForgePreferences.FPref.UI_ALT_PLAYERZONETABS);
|
||||
enableUIMask = prefs.getPref(ForgePreferences.FPref.UI_ENABLE_BORDER_MASKING);
|
||||
if (prefs.getPref(ForgePreferences.FPref.UI_ENABLE_BORDER_MASKING).equals("true")) //override old settings if not updated
|
||||
enableUIMask = "Full";
|
||||
else if (prefs.getPref(ForgePreferences.FPref.UI_ENABLE_BORDER_MASKING).equals("false"))
|
||||
enableUIMask = "Off";
|
||||
enablePreloadExtendedArt = prefs.getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_PRELOAD_EXTENDED_ART);
|
||||
locale = prefs.getPref(ForgePreferences.FPref.UI_LANGUAGE);
|
||||
autoCache = prefs.getPrefBoolean(ForgePreferences.FPref.UI_AUTO_CACHE_SIZE);
|
||||
disposeTextures = prefs.getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_DISPOSE_TEXTURES);
|
||||
CJK_Font = prefs.getPref(ForgePreferences.FPref.UI_CJK_FONT);
|
||||
|
||||
if (autoCache) {
|
||||
//increase cacheSize for devices with RAM more than 5GB, default is 400. Some phones have more than 10GB RAM (Mi 10, OnePlus 8, S20, etc..)
|
||||
if (totalDeviceRAM > 5000) //devices with more than 10GB RAM will have 800 Cache size, 600 Cache size for morethan 5GB RAM
|
||||
cacheSize = totalDeviceRAM > 10000 ? 800 : 600;
|
||||
}
|
||||
//init cache
|
||||
ImageCache.initCache(cacheSize);
|
||||
final Localizer localizer = Localizer.getInstance();
|
||||
|
||||
//load model on background thread (using progress bar to report progress)
|
||||
super.create();
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//see if app or assets need updating
|
||||
AssetsDownloader.checkForUpdates(splashScreen);
|
||||
if (exited) {
|
||||
return;
|
||||
} //don't continue if user chose to exit or couldn't download required assets
|
||||
|
||||
FModel.initialize(splashScreen.getProgressBar(), null);
|
||||
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblLoadingFonts"));
|
||||
FSkinFont.preloadAll(locale);
|
||||
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblLoadingCardTranslations"));
|
||||
CardTranslation.preloadTranslation(locale, ForgeConstants.LANG_DIR);
|
||||
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup"));
|
||||
|
||||
//add reminder to preload
|
||||
if (enablePreloadExtendedArt) {
|
||||
if (autoCache)
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblPreloadExtendedArt") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize);
|
||||
else
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblPreloadExtendedArt"));
|
||||
} else {
|
||||
if (autoCache)
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize);
|
||||
else
|
||||
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup"));
|
||||
}
|
||||
|
||||
Gdx.app.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
FSkin.loadFull(splashScreen);
|
||||
|
||||
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music
|
||||
destroyThis = false; //Allow back()
|
||||
Gdx.input.setCatchKey(Input.Keys.MENU, true);
|
||||
//openHomeScreen(-1); //default for startup
|
||||
splashScreen = null;
|
||||
|
||||
|
||||
//adjust height modifier
|
||||
|
||||
//update landscape mode preference if it doesn't match what the app loaded as
|
||||
if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_LANDSCAPE_MODE)) {
|
||||
FModel.getPreferences().setPref(ForgePreferences.FPref.UI_LANDSCAPE_MODE, true);
|
||||
FModel.getPreferences().save();
|
||||
}
|
||||
|
||||
resLoaded();
|
||||
if (!enablePreloadExtendedArt)
|
||||
return;
|
||||
List<String> borderlessCardlistkeys = FileUtil.readFile(ForgeConstants.BORDERLESS_CARD_LIST_FILE);
|
||||
if (borderlessCardlistkeys.isEmpty())
|
||||
return;
|
||||
List<String> filteredkeys = new ArrayList<>();
|
||||
for (String cardname : borderlessCardlistkeys) {
|
||||
File image = new File(ForgeConstants.CACHE_CARD_PICS_DIR + ForgeConstants.PATH_SEPARATOR + cardname + ".jpg");
|
||||
if (image.exists())
|
||||
filteredkeys.add(cardname);
|
||||
}
|
||||
if (!filteredkeys.isEmpty())
|
||||
ImageCache.preloadCache(filteredkeys);
|
||||
/* call preloadExtendedArt here, if we put it above we will *
|
||||
* get error: No OpenGL context found in the current thread. */
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Main entry point
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Sentry.init();
|
||||
SentryClient sentryClient = Sentry.getStoredClient();
|
||||
sentryClient.setRelease(BuildInfo.getVersionString());
|
||||
sentryClient.setEnvironment(System.getProperty("os.name"));
|
||||
sentryClient.addTag("Java Version", System.getProperty("java.version"));
|
||||
|
||||
// HACK - temporary solution to "Comparison method violates it's general contract!" crash
|
||||
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
|
||||
|
||||
//Turn off the Java 2D system's use of Direct3D to improve rendering speed (particularly when Full Screen)
|
||||
System.setProperty("sun.java2d.d3d", "false");
|
||||
|
||||
|
||||
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
|
||||
config.setResizable(false);
|
||||
StartAdventure start=new StartAdventure();
|
||||
|
||||
if (Config.instance().getSettingData().fullScreen)
|
||||
{
|
||||
config.setFullscreenMode(Lwjgl3ApplicationConfiguration.getDisplayMode());
|
||||
} else {
|
||||
config.setWindowedMode(Config.instance().getSettingData().width, Config.instance().getSettingData().height);
|
||||
}
|
||||
|
||||
config.setWindowIcon(Config.instance().getFilePath("forge-adventure.png"));
|
||||
|
||||
new Lwjgl3Application(start, config);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
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;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import forge.adventure.stage.SpriteGroup;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* CharacterSprite base class for animated sprites on the map
|
||||
*/
|
||||
|
||||
public class CharacterSprite extends MapActor {
|
||||
private final HashMap<AnimationTypes, HashMap<AnimationDirections, Animation<TextureRegion>>> animations = new HashMap<>();
|
||||
float timer;
|
||||
private Animation<TextureRegion> currentAnimation = null;
|
||||
private AnimationTypes currentAnimationType = AnimationTypes.Idle;
|
||||
private AnimationDirections currentAnimationDir = AnimationDirections.None;
|
||||
private Sprite avatar;
|
||||
|
||||
public CharacterSprite(String path) {
|
||||
collisionHeight=0.4f;
|
||||
load(path);
|
||||
}
|
||||
|
||||
protected void load(String path) {
|
||||
TextureAtlas atlas = Config.instance().getAtlas(path);
|
||||
for (Texture texture : new ObjectSet.ObjectSetIterator<>( atlas.getTextures()))
|
||||
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||
animations.clear();
|
||||
for (AnimationTypes stand : AnimationTypes.values()) {
|
||||
if (stand == AnimationTypes.Avatar) {
|
||||
avatar = atlas.createSprite(stand.toString());
|
||||
continue;
|
||||
}
|
||||
HashMap<AnimationDirections, Animation<TextureRegion>> dirs = new HashMap<>();
|
||||
for (AnimationDirections dir : AnimationDirections.values()) {
|
||||
|
||||
Array<Sprite> anim;
|
||||
if (dir == AnimationDirections.None)
|
||||
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));
|
||||
}
|
||||
}
|
||||
animations.put(stand, dirs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (AnimationTypes stand : AnimationTypes.values()) {
|
||||
if (stand == AnimationTypes.Avatar) {
|
||||
continue;
|
||||
}
|
||||
HashMap<AnimationDirections, Animation<TextureRegion>> dirs = animations.get(stand);
|
||||
|
||||
if (!dirs.containsKey(AnimationDirections.None) && dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.None, (dirs.get(AnimationDirections.Right)));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.Right) && dirs.containsKey(AnimationDirections.None)) {
|
||||
dirs.put(AnimationDirections.Right, (dirs.get(AnimationDirections.None)));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.Left) && dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.Left, FlipAnimation(dirs.get(AnimationDirections.Right)));
|
||||
}
|
||||
if (dirs.containsKey(AnimationDirections.Left) && !dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.Right, FlipAnimation(dirs.get(AnimationDirections.Left)));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.LeftUp) && dirs.containsKey(AnimationDirections.Left)) {
|
||||
dirs.put(AnimationDirections.LeftUp, dirs.get(AnimationDirections.Left));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.LeftDown) && dirs.containsKey(AnimationDirections.Left)) {
|
||||
dirs.put(AnimationDirections.LeftDown, dirs.get(AnimationDirections.Left));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.RightDown) && dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.RightDown, dirs.get(AnimationDirections.Right));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.RightUp) && dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.RightUp, dirs.get(AnimationDirections.Right));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.Up) && dirs.containsKey(AnimationDirections.Right)) {
|
||||
dirs.put(AnimationDirections.Up, dirs.get(AnimationDirections.Right));
|
||||
}
|
||||
if (!dirs.containsKey(AnimationDirections.Down) && dirs.containsKey(AnimationDirections.Left)) {
|
||||
dirs.put(AnimationDirections.Down, dirs.get(AnimationDirections.Left));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setAnimation(AnimationTypes.Idle);
|
||||
setDirection(AnimationDirections.Right);
|
||||
}
|
||||
|
||||
static public Animation<TextureRegion> FlipAnimation(Animation<TextureRegion> anim) {
|
||||
TextureRegion[] texReg = anim.getKeyFrames();
|
||||
Array<TextureRegion> newReg = new Array<>();
|
||||
for (TextureRegion reg : texReg) {
|
||||
TextureRegion cpy = new TextureRegion(reg);
|
||||
cpy.flip(true, false);
|
||||
newReg.add(cpy);
|
||||
}
|
||||
return new Animation<>(anim.getFrameDuration(), newReg);
|
||||
}
|
||||
|
||||
public void setAnimation(AnimationTypes type) {
|
||||
if (currentAnimationType != type) {
|
||||
currentAnimationType = type;
|
||||
updateAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnimation() {
|
||||
AnimationTypes aniType = currentAnimationType;
|
||||
AnimationDirections aniDir = currentAnimationDir;
|
||||
if (!animations.containsKey(aniType)) {
|
||||
aniType = AnimationTypes.Idle;
|
||||
}
|
||||
if (!animations.containsKey(aniType)) {
|
||||
return;
|
||||
}
|
||||
HashMap<AnimationDirections, Animation<TextureRegion>> dirs = animations.get(aniType);
|
||||
|
||||
if (!dirs.containsKey(aniDir)) {
|
||||
aniDir = AnimationDirections.Right;
|
||||
}
|
||||
if (!dirs.containsKey(aniDir)) {
|
||||
return;
|
||||
}
|
||||
currentAnimation = dirs.get(aniDir);
|
||||
}
|
||||
|
||||
public void setDirection(AnimationDirections dir) {
|
||||
if (currentAnimationDir != dir) {
|
||||
currentAnimationDir = dir;
|
||||
updateAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void positionChanged() {
|
||||
Actor parent = getParent();
|
||||
if (parent instanceof SpriteGroup) {
|
||||
((SpriteGroup) parent).UpdateActorZ(this);
|
||||
}
|
||||
super.positionChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveBy(float x, float y) {
|
||||
super.moveBy(x, y);
|
||||
if (x == 0 && y == 0) {
|
||||
return;
|
||||
}
|
||||
Vector2 vec = new Vector2(x, y);
|
||||
float degree = vec.angleDeg();
|
||||
|
||||
setAnimation(AnimationTypes.Walk);
|
||||
if (degree < 22.5)
|
||||
setDirection(AnimationDirections.Right);
|
||||
else if (degree < 22.5 + 45)
|
||||
setDirection(AnimationDirections.RightUp);
|
||||
else if (degree < 22.5 + 45 * 2)
|
||||
setDirection(AnimationDirections.Up);
|
||||
else if (degree < 22.5 + 45 * 3)
|
||||
setDirection(AnimationDirections.LeftUp);
|
||||
else if (degree < 22.5 + 45 * 4)
|
||||
setDirection(AnimationDirections.Left);
|
||||
else if (degree < 22.5 + 45 * 5)
|
||||
setDirection(AnimationDirections.LeftDown);
|
||||
else if (degree < 22.5 + 45 * 6)
|
||||
setDirection(AnimationDirections.Down);
|
||||
else if (degree < 22.5 + 45 * 7)
|
||||
setDirection(AnimationDirections.RightDown);
|
||||
else
|
||||
setDirection(AnimationDirections.Right);
|
||||
|
||||
}
|
||||
|
||||
public Vector2 pos() {
|
||||
return new Vector2(getX(), getY());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
timer += delta;
|
||||
super.act(delta);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (currentAnimation == null)
|
||||
return;
|
||||
TextureRegion currentFrame = currentAnimation.getKeyFrame(timer, true);
|
||||
setHeight(currentFrame.getRegionHeight());
|
||||
setWidth(currentFrame.getRegionWidth());
|
||||
batch.draw(currentFrame, getX(), getY());
|
||||
super.draw(batch,parentAlpha);
|
||||
//batch.draw(getDebugTexture(),getX(),getY());
|
||||
|
||||
}
|
||||
|
||||
public Sprite getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public enum AnimationTypes {
|
||||
Idle,
|
||||
Walk,
|
||||
Death,
|
||||
Attack,
|
||||
Hit,
|
||||
Avatar
|
||||
}
|
||||
|
||||
public enum AnimationDirections {
|
||||
|
||||
None,
|
||||
Right,
|
||||
RightDown,
|
||||
Down,
|
||||
LeftDown,
|
||||
Left,
|
||||
LeftUp,
|
||||
Up,
|
||||
RightUp
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.data.EnemyData;
|
||||
import forge.adventure.data.RewardData;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.Reward;
|
||||
|
||||
/**
|
||||
* EnemySprite
|
||||
* Character sprite that represents an Enemy
|
||||
*/
|
||||
public class EnemySprite extends CharacterSprite {
|
||||
EnemyData data;
|
||||
private int id;
|
||||
|
||||
public EnemySprite(EnemyData enemyData) {
|
||||
super(enemyData.sprite);
|
||||
|
||||
data = enemyData;
|
||||
}
|
||||
|
||||
public EnemySprite(int id, EnemyData enemyData) {
|
||||
this(enemyData);
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void moveTo(Actor other, float delta) {
|
||||
Vector2 diff = new Vector2(other.getX(), other.getY()).sub(pos());
|
||||
|
||||
diff.setLength(data.speed*delta);
|
||||
moveBy(diff.x, diff.y);
|
||||
}
|
||||
|
||||
public EnemyData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public Array<Reward> getRewards() {
|
||||
Array<Reward> ret=new Array<Reward>();
|
||||
if(data.rewards==null)
|
||||
return ret;
|
||||
for(RewardData rdata:data.rewards)
|
||||
{
|
||||
ret.addAll(rdata.generate(false,Current.latestDeck()!=null? Current.latestDeck().getMain().toFlatList():null));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.scene.TileMapScene;
|
||||
import forge.adventure.stage.MapStage;
|
||||
|
||||
/**
|
||||
* EntryActor
|
||||
* Used to teleport the player in and out of the map
|
||||
*/
|
||||
public class EntryActor extends MapActor{
|
||||
private final MapStage stage;
|
||||
private final int id;
|
||||
String targetMap;
|
||||
|
||||
public EntryActor(MapStage stage,String sourceMap, int id,String targetMap,float x,float y,float w,float h,String direction)
|
||||
{
|
||||
this.stage = stage;
|
||||
this.id = id;
|
||||
this.targetMap = targetMap;
|
||||
|
||||
|
||||
if((targetMap==null||targetMap.isEmpty()&&sourceMap.isEmpty())||//if target is null and "from world"
|
||||
!sourceMap.isEmpty()&&targetMap.equals(sourceMap)) //or if source is this target
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case "up":
|
||||
stage.GetPlayer().setPosition(x,y+h);
|
||||
break;
|
||||
case "down":
|
||||
stage.GetPlayer().setPosition(x,y-stage.GetPlayer().getHeight());
|
||||
break;
|
||||
case "right":
|
||||
stage.GetPlayer().setPosition(x-stage.GetPlayer().getWidth(),y);
|
||||
break;
|
||||
case "left":
|
||||
stage.GetPlayer().setPosition(x+w,y);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public MapStage getMapStage()
|
||||
{
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollide()
|
||||
{
|
||||
if(targetMap==null||targetMap.isEmpty())
|
||||
{
|
||||
stage.exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
((TileMapScene)SceneType.TileMapScene.instance).loadNext(targetMap);
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectID() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
|
||||
/**
|
||||
* Map Actor base class for Actors on the map
|
||||
* implements collision detection.
|
||||
*/
|
||||
public class MapActor extends Actor {
|
||||
|
||||
|
||||
Texture debugTexture;
|
||||
float collisionHeight=1.0f;
|
||||
private Texture getDebugTexture() {
|
||||
if (debugTexture == null) {
|
||||
Pixmap pixmap = new Pixmap((int) getWidth(), (int) getHeight(), Pixmap.Format.RGBA8888);
|
||||
pixmap.setColor(1.0f,0,0,0.5f);
|
||||
pixmap.fillRectangle(0, (int) getHeight()- (int)boundingRect.getHeight(), (int) boundingRect.getWidth(), (int) boundingRect.getHeight());
|
||||
debugTexture = new Texture(pixmap);
|
||||
pixmap.dispose();
|
||||
|
||||
}
|
||||
return debugTexture;
|
||||
}
|
||||
Rectangle boundingRect;
|
||||
|
||||
boolean isCollidingWithPlayer=false;
|
||||
protected void onPlayerCollide()
|
||||
{
|
||||
|
||||
}
|
||||
boolean boundDebug=false;
|
||||
public void setBoundDebug(boolean debug)
|
||||
{
|
||||
boundDebug=debug;
|
||||
}
|
||||
@Override
|
||||
public void draw(Batch batch, float alpha) {
|
||||
|
||||
if(boundDebug)
|
||||
batch.draw(getDebugTexture(),getX(),getY());
|
||||
}
|
||||
@Override
|
||||
protected void positionChanged() {
|
||||
|
||||
updateBoundingRect();
|
||||
super.positionChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sizeChanged() {
|
||||
super.sizeChanged();
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void updateBoundingRect() {
|
||||
boundingRect = new Rectangle(getX(), getY(), getWidth(), getHeight()*collisionHeight);
|
||||
}
|
||||
|
||||
public Rectangle boundingRect() {
|
||||
return boundingRect;
|
||||
}
|
||||
public boolean collideWithPlayer(PlayerSprite other) {
|
||||
|
||||
|
||||
boolean newIsColliding= collideWith(other);
|
||||
if(newIsColliding)
|
||||
{
|
||||
if(!isCollidingWithPlayer)
|
||||
onPlayerCollide();
|
||||
isCollidingWithPlayer=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isCollidingWithPlayer=false;
|
||||
}
|
||||
return isCollidingWithPlayer;
|
||||
}
|
||||
public boolean collideWith(Rectangle other) {
|
||||
return boundingRect().overlaps(other);
|
||||
|
||||
}
|
||||
|
||||
public boolean collideWith(MapActor other) {
|
||||
return collideWith(other.boundingRect());
|
||||
}
|
||||
|
||||
public boolean collideWith(Actor other) {
|
||||
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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
/**
|
||||
* Designed to add anonymous class for a single action on collision
|
||||
*/
|
||||
public class OnCollide extends MapActor {
|
||||
|
||||
Runnable onCollide;
|
||||
public OnCollide(Runnable func) {
|
||||
onCollide = func;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlayerCollide() {
|
||||
try {
|
||||
onCollide.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import forge.adventure.stage.GameStage;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
|
||||
/**
|
||||
* Class that will represent the player sprite on the map
|
||||
*/
|
||||
public class PlayerSprite extends CharacterSprite {
|
||||
private final float playerSpeed;
|
||||
private final Vector2 direction = Vector2.Zero.cpy();
|
||||
private float playerSpeedModifier = 1f;
|
||||
GameStage gameStage;
|
||||
public PlayerSprite(GameStage gameStage) {
|
||||
super(AdventurePlayer.current().spriteName());
|
||||
this.gameStage=gameStage;
|
||||
setOriginX(getWidth() / 2);
|
||||
Current.player().onPlayerChanged(()->updatePlayer());
|
||||
playerSpeed=Config.instance().getConfigData().playerBaseSpeed;
|
||||
}
|
||||
|
||||
private void updatePlayer() {
|
||||
load(AdventurePlayer.current().spriteName());
|
||||
}
|
||||
|
||||
public void LoadPos() {
|
||||
setPosition(AdventurePlayer.current().getWorldPosX(), AdventurePlayer.current().getWorldPosY());
|
||||
}
|
||||
|
||||
public void storePos() {
|
||||
AdventurePlayer.current().setWorldPosX(getX());
|
||||
AdventurePlayer.current().setWorldPosY(getY());
|
||||
}
|
||||
|
||||
public Vector2 getMovementDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setMovementDirection(final Vector2 dir) {
|
||||
direction.set(dir);
|
||||
}
|
||||
|
||||
public void setMoveModifier(float speed) {
|
||||
playerSpeedModifier = speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
super.act(delta);
|
||||
direction.setLength(playerSpeed * delta * playerSpeedModifier);
|
||||
|
||||
if(!direction.isZero())
|
||||
{
|
||||
|
||||
gameStage.prepareCollision(pos(),direction,boundingRect);
|
||||
direction.set(gameStage.adjustMovement(direction,boundingRect));
|
||||
moveBy(direction.x, direction.y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isMoving() {
|
||||
return !direction.isZero();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
direction.setZero();
|
||||
setAnimation(AnimationTypes.Idle);
|
||||
}
|
||||
|
||||
public void setPosition(Vector2 oldPosition) {
|
||||
setPosition(oldPosition.x,oldPosition.y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.scene.RewardScene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.util.Reward;
|
||||
|
||||
/**
|
||||
* Map actor that will open the Shop on collision
|
||||
*/
|
||||
public class ShopActor extends MapActor{
|
||||
private final MapStage stage;
|
||||
private final int id;
|
||||
Array<Reward> rewardData;
|
||||
|
||||
public ShopActor(MapStage stage, int id, Array<Reward> rewardData)
|
||||
{
|
||||
this.stage = stage;
|
||||
this.id = id;
|
||||
this.rewardData = rewardData;
|
||||
|
||||
}
|
||||
|
||||
public MapStage getMapStage()
|
||||
{
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollide()
|
||||
{
|
||||
|
||||
stage.GetPlayer().stop();
|
||||
((RewardScene) SceneType.RewardScene.instance).loadRewards(rewardData, RewardScene.Type.Shop,this);
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.RewardScene.instance);
|
||||
}
|
||||
|
||||
public int getObjectID() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
|
||||
/**
|
||||
* Class to add sprites to a map
|
||||
*/
|
||||
public class TextureSprite extends MapActor{
|
||||
|
||||
private final TextureRegion region;
|
||||
|
||||
public TextureSprite(TextureRegion region)
|
||||
{
|
||||
|
||||
this.region = region;
|
||||
setWidth(region.getRegionWidth());
|
||||
setHeight(region.getRegionHeight());
|
||||
}
|
||||
@Override
|
||||
public void draw (Batch batch, float parentAlpha) {
|
||||
batch.draw(region,getX(),getY(),getWidth(),getHeight());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for the biomes
|
||||
*/
|
||||
public class BiomeData implements Serializable {
|
||||
private final Random rand = new Random();
|
||||
public float startPointX;
|
||||
public float startPointY;
|
||||
public float noiseWeight;
|
||||
public float distWeight;
|
||||
public String name;
|
||||
public String tilesetAtlas;
|
||||
public String tilesetName;
|
||||
public BiomeTerrainData[] terrain;
|
||||
public float width;
|
||||
public float height;
|
||||
public String color;
|
||||
public boolean invertHeight;
|
||||
public String[] spriteNames;
|
||||
public List<String> enemies;
|
||||
public List<String> pointsOfInterest;
|
||||
|
||||
private ArrayList<EnemyData> enemyList;
|
||||
private ArrayList<PointOfInterestData> pointOfInterestList;
|
||||
|
||||
public Color GetColor() {
|
||||
return Color.valueOf(color);
|
||||
}
|
||||
|
||||
public ArrayList<EnemyData> getEnemyList() {
|
||||
if (enemyList == null) {
|
||||
enemyList = new ArrayList<EnemyData>();
|
||||
if (enemies == null)
|
||||
return enemyList;
|
||||
for (EnemyData data : new Array.ArrayIterator<>(WorldData.getAllEnemies())) {
|
||||
if (enemies.contains(data.name)) {
|
||||
enemyList.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return enemyList;
|
||||
}
|
||||
|
||||
public ArrayList<PointOfInterestData> getPointsOfInterest() {
|
||||
if (pointOfInterestList == null) {
|
||||
pointOfInterestList = new ArrayList<PointOfInterestData>();
|
||||
if(pointsOfInterest==null)
|
||||
return pointOfInterestList;
|
||||
Array<PointOfInterestData> allTowns = PointOfInterestData.getAllPointOfInterest();
|
||||
for (PointOfInterestData data : new Array.ArrayIterator<>(allTowns)) {
|
||||
if (pointsOfInterest.contains(data.name)) {
|
||||
pointOfInterestList.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pointOfInterestList;
|
||||
}
|
||||
|
||||
public EnemyData getEnemy(float difficultyFactor) {
|
||||
EnemyData bestData=null;
|
||||
float biggestNumber=0;
|
||||
for (EnemyData data : enemyList) {
|
||||
float newNumber=data.spawnRate *rand.nextFloat()*difficultyFactor;
|
||||
if (newNumber>biggestNumber) {
|
||||
biggestNumber=newNumber;
|
||||
bestData=data;
|
||||
}
|
||||
}
|
||||
return bestData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeSpriteData
|
||||
* contains the information for the sprites on the map like trees and rocks
|
||||
*/
|
||||
public class BiomeSpriteData implements Serializable {
|
||||
public String name;
|
||||
public double startArea;
|
||||
public double endArea;
|
||||
public double density;
|
||||
public double resolution;
|
||||
public int layer;
|
||||
|
||||
public String key() {
|
||||
return "BiomeSprite&" + name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for the terrain distribution
|
||||
*/
|
||||
public class BiomeTerrainData {
|
||||
//sprite name in the biome atlas file
|
||||
public String spriteName;
|
||||
//minimum noise value where to place the terrain
|
||||
public float min;
|
||||
//maximum noise value where to place the terrain
|
||||
public float max;
|
||||
// factor for the noise resolution
|
||||
public float resolution;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains general information about the game
|
||||
*/
|
||||
public class ConfigData {
|
||||
public int screenWidth;
|
||||
public int screenHeight;
|
||||
public String skin;
|
||||
public String font;
|
||||
public String fontColor;
|
||||
public int minDeckSize;
|
||||
public float playerBaseSpeed;
|
||||
public String[] starterDecks;
|
||||
public DifficultyData[] difficulties;
|
||||
public RewardData legalCards;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for the difficulties
|
||||
*/
|
||||
public class DifficultyData {
|
||||
public String name="";
|
||||
public int startingLife=10;
|
||||
public int staringMoney=10;
|
||||
public float enemyLifeFactor=1;
|
||||
public boolean startingDifficulty;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import forge.adventure.util.CardUtil;
|
||||
import forge.deck.Deck;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information of enemies
|
||||
*/
|
||||
public class EnemyData {
|
||||
public String name;
|
||||
public String sprite;
|
||||
public String deck;
|
||||
public float spawnRate;
|
||||
public float difficulty;
|
||||
public float speed;
|
||||
public int life;
|
||||
public RewardData[] rewards;
|
||||
|
||||
public EnemyData()
|
||||
{
|
||||
|
||||
}
|
||||
public EnemyData(EnemyData enemyData) {
|
||||
name =enemyData.name;
|
||||
sprite =enemyData.sprite;
|
||||
deck =enemyData.deck;
|
||||
spawnRate =enemyData.spawnRate;
|
||||
difficulty =enemyData.difficulty ;
|
||||
speed =enemyData.speed;
|
||||
life =enemyData.life;
|
||||
if(enemyData.rewards==null)
|
||||
{
|
||||
rewards=null;
|
||||
}
|
||||
else
|
||||
{
|
||||
rewards =new RewardData[enemyData.rewards.length];
|
||||
for(int i=0;i<rewards.length;i++)
|
||||
rewards[i]=new RewardData(enemyData.rewards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public Deck generateDeck() {
|
||||
return CardUtil.getDeck(deck);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for a generated deck
|
||||
*
|
||||
* if the template is null then it will use just the reward information of mainDeck and sideBoard
|
||||
*/
|
||||
public class GeneratedDeckData {
|
||||
public String name;
|
||||
public GeneratedDeckTemplateData template;
|
||||
public RewardData[] mainDeck;
|
||||
public RewardData[] sideBoard;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for the generated deck
|
||||
*/
|
||||
public class GeneratedDeckTemplateData {
|
||||
public String[] colors;
|
||||
public int count;
|
||||
public float rares;
|
||||
public String tribe;
|
||||
public float tribeSynergyCards=0.6f;
|
||||
public float tribeCards=1.0f;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information possible hero sprite
|
||||
*/
|
||||
public class HeroData {
|
||||
public String name;
|
||||
public String female;
|
||||
public String male;
|
||||
public String femaleAvatar;
|
||||
public String maleAvatar;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
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.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the a list of all heroes
|
||||
*/
|
||||
public class HeroListData {
|
||||
static private HeroListData instance;
|
||||
public HeroData[] heroes;
|
||||
public String avatar;
|
||||
private TextureAtlas avatarSprites;
|
||||
|
||||
static private HeroListData read() {
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.HEROES);
|
||||
if (handle.exists()) {
|
||||
instance = json.fromJson(HeroListData.class, handle);
|
||||
instance.avatarSprites = Config.instance().getAtlas(instance.avatar);
|
||||
|
||||
instance.avatarSprites.getTextures().first().setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static public String getHero(int raceIndex, boolean female) {
|
||||
if (instance == null)
|
||||
instance = read();
|
||||
HeroData data = instance.heroes[raceIndex];
|
||||
|
||||
if (female)
|
||||
return data.female;
|
||||
return data.male;
|
||||
|
||||
}
|
||||
|
||||
public static TextureRegion getAvatar(int heroRace, boolean isFemale, int avatarIndex) {
|
||||
|
||||
if (instance == null)
|
||||
instance = read();
|
||||
HeroData data = instance.heroes[heroRace];
|
||||
Array<Sprite> sprites;
|
||||
if (isFemale)
|
||||
sprites = instance.avatarSprites.createSprites(data.femaleAvatar);
|
||||
else
|
||||
sprites = instance.avatarSprites.createSprites(data.maleAvatar);
|
||||
avatarIndex %= sprites.size;
|
||||
if (avatarIndex < 0) {
|
||||
avatarIndex += sprites.size;
|
||||
}
|
||||
return sprites.get(avatarIndex);
|
||||
}
|
||||
|
||||
public static Array<String> getRaces() {
|
||||
if (instance == null)
|
||||
instance = read();
|
||||
Array<String> ret = new Array<>();
|
||||
for (HeroData hero : instance.heroes) {
|
||||
ret.add(hero.name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for the point of interests like towns and dungeons
|
||||
*/
|
||||
public class PointOfInterestData {
|
||||
public String name;
|
||||
public String type;
|
||||
public int count;
|
||||
public String spriteAtlas;
|
||||
public String sprite;
|
||||
public String map;
|
||||
public float radiusFactor;
|
||||
|
||||
|
||||
|
||||
private static Array<PointOfInterestData> pointOfInterestList;
|
||||
public static Array<PointOfInterestData> getAllPointOfInterest() {
|
||||
if (pointOfInterestList == null) {
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.POINTS_OF_INTEREST);
|
||||
if (handle.exists()) {
|
||||
Array readJson = json.fromJson(Array.class, PointOfInterestData.class, handle);
|
||||
pointOfInterestList = readJson;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return pointOfInterestList;
|
||||
}
|
||||
public static PointOfInterestData getPointOfInterest(String name) {
|
||||
for(PointOfInterestData data: new Array.ArrayIterator<>(getAllPointOfInterest()))
|
||||
{
|
||||
if(data.name.equals(name))
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.google.common.collect.Iterables;
|
||||
import forge.StaticData;
|
||||
import forge.adventure.util.CardUtil;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Reward;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* BiomeData
|
||||
* contains the information for a "reward"
|
||||
* that can be a random card, gold or items.
|
||||
* Also used for deck generation and shops
|
||||
*/
|
||||
public class RewardData {
|
||||
public String type;
|
||||
public float probability;
|
||||
public int count;
|
||||
public int addMaxCount;
|
||||
public String cardName;
|
||||
public String itemName;
|
||||
public String[] editions;
|
||||
public String[] colors;
|
||||
public String[] rarity;
|
||||
public String[] subTypes;
|
||||
public String[] cardTypes;
|
||||
public String[] superTypes;
|
||||
public int[] manaCosts;
|
||||
public String[] keyWords;
|
||||
public String colorType;
|
||||
public String cardText;
|
||||
public boolean matchAllSubTypes;
|
||||
|
||||
|
||||
public RewardData()
|
||||
{
|
||||
|
||||
}
|
||||
public RewardData(RewardData rewardData) {
|
||||
type =rewardData.type;
|
||||
probability =rewardData.probability;
|
||||
count =rewardData.count;
|
||||
addMaxCount =rewardData.addMaxCount;
|
||||
cardName =rewardData.cardName;
|
||||
itemName =rewardData.itemName;
|
||||
editions =rewardData.editions==null?null:rewardData.editions.clone();
|
||||
colors =rewardData.colors==null?null:rewardData.colors.clone();
|
||||
rarity =rewardData.rarity==null?null:rewardData.rarity.clone();
|
||||
subTypes =rewardData.subTypes==null?null:rewardData.subTypes.clone();
|
||||
cardTypes =rewardData.cardTypes==null?null:rewardData.cardTypes.clone();
|
||||
superTypes =rewardData.superTypes==null?null:rewardData.superTypes.clone();
|
||||
manaCosts =rewardData.manaCosts==null?null:rewardData.manaCosts.clone();
|
||||
keyWords =rewardData.keyWords==null?null:rewardData.keyWords.clone();
|
||||
colorType =rewardData.colorType;
|
||||
cardText =rewardData.cardText;
|
||||
matchAllSubTypes =rewardData.matchAllSubTypes;
|
||||
}
|
||||
|
||||
private static Iterable<PaperCard> allCards;
|
||||
private static Iterable<PaperCard> allEnemyCards;
|
||||
public Array<Reward> generate(boolean isForEnemy)
|
||||
{
|
||||
return generate(isForEnemy,null);
|
||||
}
|
||||
public Array<Reward> generate(boolean isForEnemy,Iterable<PaperCard> cards)
|
||||
{
|
||||
if(allCards==null)
|
||||
{
|
||||
RewardData legals=Config.instance().getConfigData().legalCards;
|
||||
if(legals==null)
|
||||
{
|
||||
allCards = FModel.getMagicDb().getCommonCards().getUniqueCardsNoAlt();
|
||||
}
|
||||
else
|
||||
{
|
||||
allCards = Iterables.filter(FModel.getMagicDb().getCommonCards().getUniqueCardsNoAlt(), new CardUtil.CardPredicate(legals, true));
|
||||
}
|
||||
allEnemyCards=Iterables.filter(allCards, input -> {
|
||||
if(input==null)return false;
|
||||
return !input.getRules().getAiHints().getRemAIDecks();
|
||||
});
|
||||
}
|
||||
Array<Reward> ret=new Array<>();
|
||||
if(probability==0|| WorldSave.getCurrentSave().getWorld().getRandom().nextFloat()<=probability)
|
||||
{
|
||||
if(type==null||type.isEmpty())
|
||||
type="randomCard";
|
||||
int addedCount=(int)((float)(addMaxCount)* WorldSave.getCurrentSave().getWorld().getRandom().nextFloat());
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case "card":
|
||||
case "randomCard":
|
||||
if(cardName!=null&&!cardName.isEmpty())
|
||||
{
|
||||
for(int i=0;i<count+addedCount;i++)
|
||||
{
|
||||
ret.add(new Reward(StaticData.instance().getCommonCards().getCard(cardName)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(PaperCard card:CardUtil.generateCards(isForEnemy?allEnemyCards:allCards,this, count+addedCount))
|
||||
{
|
||||
ret.add(new Reward(card));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "deckCard":
|
||||
if(cards==null)return ret;
|
||||
for(PaperCard card: CardUtil.generateCards(cards,this, count+addedCount))
|
||||
{
|
||||
ret.add(new Reward(card));
|
||||
}
|
||||
break;
|
||||
case "gold":
|
||||
ret.add(new Reward(count+addedCount));
|
||||
break;
|
||||
case "life":
|
||||
ret.add(new Reward(Reward.Type.Life, count+addedCount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public List<PaperCard> generateAllCards(Iterable<RewardData> dataList, boolean isForEnemy)
|
||||
{
|
||||
|
||||
return rewardsToCards(generateAll(dataList, isForEnemy));
|
||||
}
|
||||
static public Iterable<Reward> generateAll(Iterable<RewardData> dataList, boolean isForEnemy)
|
||||
{
|
||||
Array<Reward> ret=new Array<Reward>();
|
||||
for (RewardData data:dataList)
|
||||
ret.addAll(data.generate(isForEnemy));
|
||||
return ret;
|
||||
}
|
||||
static public List<PaperCard> rewardsToCards(Iterable<Reward> dataList)
|
||||
{
|
||||
ArrayList<PaperCard> ret=new ArrayList<PaperCard>();
|
||||
for (Reward data:dataList)
|
||||
{
|
||||
ret.add(data.getCard());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* SettingData
|
||||
* contains settings outside of the chosen adventure
|
||||
*/
|
||||
public class SettingData {
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
public String plane;
|
||||
public boolean fullScreen;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* SettingData
|
||||
* contains data for a Shop on the map
|
||||
*/
|
||||
public class ShopData {
|
||||
|
||||
public String name;
|
||||
public String spriteAtlas;
|
||||
public String sprite;
|
||||
public Array<RewardData> rewards;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.OrderedMap;
|
||||
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* UIData
|
||||
* contains a GUI definition, used for most user interfaces to customize the UI
|
||||
*/
|
||||
public class UIData {
|
||||
public int width;
|
||||
public int height;
|
||||
public boolean yDown;
|
||||
public Array<OrderedMap<String,String>> elements;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package forge.adventure.data;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
import forge.adventure.world.BiomeSprites;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* Data class that will be used to read Json configuration files
|
||||
* UIData
|
||||
* contains the definition of the world
|
||||
*/
|
||||
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;
|
||||
private BiomeSprites sprites;
|
||||
private List<BiomeData> biomes;
|
||||
private static Array<ShopData> shopList;
|
||||
|
||||
|
||||
public static Array<ShopData> getShopList() {
|
||||
if (shopList == null) {
|
||||
shopList = new Array<>();
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.SHOPS);
|
||||
if (handle.exists())
|
||||
{
|
||||
|
||||
Array readList = json.fromJson(Array.class, ShopData.class, handle);
|
||||
shopList = readList;
|
||||
}
|
||||
}
|
||||
return shopList;
|
||||
}
|
||||
static public Array<EnemyData> getAllEnemies() {
|
||||
if (allEnemies == null) {
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.ENEMIES);
|
||||
if (handle.exists())
|
||||
{
|
||||
|
||||
Array readList = json.fromJson(Array.class, EnemyData.class, handle);
|
||||
allEnemies = readList;
|
||||
}
|
||||
}
|
||||
return allEnemies;
|
||||
}
|
||||
|
||||
public static EnemyData getEnemy(String enemy) {
|
||||
for(EnemyData data: new Array.ArrayIterator<>(getAllEnemies()))
|
||||
{
|
||||
if(data.name.equals(enemy))
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BiomeSprites GetBiomeSprites() {
|
||||
if (sprites == null) {
|
||||
Json json = new Json();
|
||||
sprites = (json.fromJson(BiomeSprites.class, Config.instance().getFile(biomesSprites)));
|
||||
}
|
||||
return sprites;
|
||||
}
|
||||
|
||||
public List<BiomeData> GetBiomes() {
|
||||
if (biomes == null) {
|
||||
biomes = new ArrayList<BiomeData>();
|
||||
Json json = new Json();
|
||||
for (String name : biomesNames) {
|
||||
biomes.add(json.fromJson(BiomeData.class, Config.instance().getFile(name)));
|
||||
}
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class DocumentChangeListener implements DocumentListener {
|
||||
private final Runnable run;
|
||||
|
||||
public DocumentChangeListener(Runnable run)
|
||||
{
|
||||
this.run = run;
|
||||
}
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
|
||||
changedUpdate(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
changedUpdate(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
run.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class EditorMainWindow extends JFrame {
|
||||
JTabbedPane tabs =new JTabbedPane();
|
||||
|
||||
public EditorMainWindow()
|
||||
{
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(tabs);
|
||||
tabs.addTab("Enemies",new EnemyEditor());
|
||||
setVisible(true);
|
||||
setSize(800,600);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
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 {
|
||||
EnemyData currentData;
|
||||
|
||||
|
||||
JTextField nameField=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));
|
||||
FilePicker deck=new FilePicker(new String[]{"dck","json"});
|
||||
FilePicker atlas=new FilePicker(new String[]{"atlas"});
|
||||
RewardsEditor rewards=new RewardsEditor();
|
||||
SwingAtlasPreview preview=new SwingAtlasPreview();
|
||||
private boolean updating=false;
|
||||
|
||||
public EnemyEdit()
|
||||
{
|
||||
|
||||
JComponent center=new JComponent() { };
|
||||
center.setLayout(new GridLayout(8,2));
|
||||
|
||||
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);
|
||||
BorderLayout layout=new BorderLayout();
|
||||
setLayout(layout);
|
||||
add(center,BorderLayout.PAGE_START);
|
||||
add(rewards,BorderLayout.CENTER);
|
||||
add(preview,BorderLayout.LINE_START);
|
||||
|
||||
atlas.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateEnemy()));
|
||||
nameField.getDocument().addDocumentListener(new DocumentChangeListener(()->updateEnemy()));
|
||||
deck.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateEnemy()));
|
||||
lifeFiled.addChangeListener(e -> updateEnemy());
|
||||
speed.addChangeListener(e -> updateEnemy());
|
||||
difficulty.addChangeListener(e -> updateEnemy());
|
||||
spawnRate.addChangeListener(e -> updateEnemy());
|
||||
rewards.addChangeListener(e -> updateEnemy());
|
||||
lifeFiled.addChangeListener(e -> updateEnemy());
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void updateEnemy() {
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
currentData.name=nameField.getText();
|
||||
currentData.life= (int) lifeFiled.getValue();
|
||||
currentData.sprite= atlas.getEdit().getText();
|
||||
currentData.speed= ((Double) speed.getValue()).floatValue();
|
||||
currentData.spawnRate=((Double) spawnRate.getValue()).floatValue();
|
||||
currentData.difficulty=((Double) difficulty.getValue()).floatValue();
|
||||
currentData.deck= deck.getEdit().getText();
|
||||
currentData.rewards= rewards.getRewards();
|
||||
preview.setSpritePath(currentData.sprite);
|
||||
}
|
||||
|
||||
public void setCurrentEnemy(EnemyData data)
|
||||
{
|
||||
currentData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
nameField.setText(currentData.name);
|
||||
lifeFiled.setValue(currentData.life);
|
||||
atlas.getEdit().setText(currentData.sprite);
|
||||
deck.getEdit().setText(currentData.deck);
|
||||
speed.setValue(new Float(currentData.speed).doubleValue());
|
||||
spawnRate.setValue(new Float(currentData.spawnRate).doubleValue());
|
||||
difficulty.setValue(new Float(currentData.difficulty).doubleValue());
|
||||
rewards.setRewards(currentData.rewards);
|
||||
preview.setSpritePath(currentData.sprite);
|
||||
updating=false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
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.EnemyData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class EnemyEditor extends JComponent {
|
||||
DefaultListModel<EnemyData> model = new DefaultListModel<>();
|
||||
JList<EnemyData> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
EnemyEdit edit=new EnemyEdit();
|
||||
|
||||
|
||||
|
||||
public class EnemyDataRenderer 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 EnemyData))
|
||||
return label;
|
||||
EnemyData enemy=(EnemyData) value;
|
||||
// Get the renderer component from parent class
|
||||
|
||||
label.setText(enemy.name);
|
||||
SwingAtlas atlas=new SwingAtlas(Config.instance().getFile(enemy.sprite));
|
||||
if(atlas.has("Avatar"))
|
||||
label.setIcon(atlas.get("Avatar"));
|
||||
else
|
||||
{
|
||||
ImageIcon img=atlas.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 EnemyEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new EnemyDataRenderer());
|
||||
list.addListSelectionListener(e -> updateEdit());
|
||||
addButton("add",e->addEnemy());
|
||||
addButton("remove",e->remove());
|
||||
addButton("copy",e->copy());
|
||||
addButton("load",e->load());
|
||||
addButton("save",e->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;
|
||||
EnemyData data=new EnemyData(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrentEnemy(model.get(selected));
|
||||
}
|
||||
|
||||
void save()
|
||||
{
|
||||
Array<EnemyData> 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.ENEMIES);
|
||||
handle.writeString(json.prettyPrint(json.toJson(allEnemies,Array.class, EnemyData.class)),false);
|
||||
|
||||
}
|
||||
void load()
|
||||
{
|
||||
model.clear();
|
||||
Array<EnemyData> allEnemies=new Array<>();
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(Paths.ENEMIES);
|
||||
if (handle.exists())
|
||||
{
|
||||
Array readEnemies=json.fromJson(Array.class, EnemyData.class, handle);
|
||||
allEnemies = readEnemies;
|
||||
}
|
||||
for (int i=0;i<allEnemies.size;i++) {
|
||||
model.add(i,allEnemies.get(i));
|
||||
}
|
||||
}
|
||||
void addEnemy()
|
||||
{
|
||||
EnemyData data=new EnemyData();
|
||||
data.name="Enemy "+model.getSize();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class FilePicker extends Box {
|
||||
JTextField edit=new JTextField();
|
||||
JButton findButton=new JButton(UIManager.getIcon("FileView.directoryIcon"));
|
||||
private final String[] fileEndings;
|
||||
|
||||
public FilePicker(String[] fileEndings) {
|
||||
super(BoxLayout.X_AXIS);
|
||||
this.fileEndings = fileEndings;
|
||||
|
||||
findButton.addActionListener(e->find());
|
||||
|
||||
add(edit);
|
||||
add(findButton);
|
||||
|
||||
}
|
||||
JTextField getEdit()
|
||||
{
|
||||
return edit;
|
||||
}
|
||||
|
||||
private void find() {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Config.instance().getFilePath(edit.getText())));
|
||||
fc.setFileFilter( new FileNameExtensionFilter("Pick File",fileEndings));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
if (fc.showOpenDialog(this) ==
|
||||
JFileChooser.APPROVE_OPTION) {
|
||||
File selected = fc.getSelectedFile();
|
||||
|
||||
try {
|
||||
if (selected != null&&selected.getCanonicalPath().startsWith(new File(Config.instance().getFilePath("")).getCanonicalPath())) {
|
||||
edit.setText(selected.getCanonicalPath().substring(new File(Config.instance().getFilePath("")).getCanonicalPath().length()+1).replace('\\','/'));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Config.instance();
|
||||
new EditorMainWindow();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.RewardData;
|
||||
import forge.card.CardType;
|
||||
import forge.game.keyword.Keyword;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class RewardEdit extends JComponent {
|
||||
RewardData currentData;
|
||||
|
||||
JComboBox typeField =new JComboBox(new String[] { "card", "gold", "life", "deckCard", "item"});
|
||||
JSpinner probability = new JSpinner(new SpinnerNumberModel(0f, 0, 1, 0.1f));
|
||||
JSpinner count = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
|
||||
JSpinner addMaxCount = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
|
||||
JTextField cardName =new JTextField();
|
||||
JTextField itemName =new JTextField();
|
||||
TextListEdit editions =new TextListEdit();
|
||||
TextListEdit colors =new TextListEdit(new String[] { "White", "Blue", "Black", "Red", "Green" });
|
||||
TextListEdit rarity =new TextListEdit(new String[] { "Basic Land", "Common", "Uncommon", "Rare", "Mythic Rare" });
|
||||
TextListEdit subTypes =new TextListEdit();
|
||||
TextListEdit cardTypes =new TextListEdit(Arrays.asList(CardType.CoreType.values()).stream().map(CardType.CoreType::toString).toArray(String[]::new));
|
||||
TextListEdit superTypes =new TextListEdit(Arrays.asList(CardType.Supertype.values()).stream().map(CardType.Supertype::toString).toArray(String[]::new));
|
||||
TextListEdit manaCosts =new TextListEdit();
|
||||
TextListEdit keyWords =new TextListEdit(Arrays.asList(Keyword.values()).stream().map(Keyword::toString).toArray(String[]::new));
|
||||
JComboBox colorType =new JComboBox(new String[] { "Any", "Colorless", "MultiColor", "MonoColor"});
|
||||
JTextField cardText =new JTextField();
|
||||
private boolean updating=false;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
typeField.addActionListener(((e)->updateReward()));
|
||||
probability.addChangeListener(e->updateReward());
|
||||
count.addChangeListener(e->updateReward());
|
||||
addMaxCount.addChangeListener(e->updateReward());
|
||||
cardName.getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
itemName.getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
editions.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
colors.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
rarity.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
subTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
cardTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
superTypes.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
manaCosts.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
keyWords.getEdit().getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
colorType.addActionListener(((e)->updateReward()));
|
||||
cardText.getDocument().addDocumentListener(new DocumentChangeListener(()->updateReward()));
|
||||
|
||||
}
|
||||
|
||||
private void updateReward() {
|
||||
if(currentData==null||updating)
|
||||
return;
|
||||
|
||||
|
||||
currentData.type=typeField.getSelectedItem()==null?null:typeField.getSelectedItem().toString();
|
||||
currentData.probability=((Double)probability.getValue()).floatValue();
|
||||
currentData.count= (int) count.getValue();
|
||||
currentData.addMaxCount= (int) addMaxCount.getValue();
|
||||
currentData.cardName = cardName.getText().isEmpty()?null:cardName.getText();
|
||||
currentData.itemName = itemName.getText().isEmpty()?null:itemName.getText();
|
||||
currentData.editions = editions.getList();
|
||||
currentData.colors = colors.getList();
|
||||
currentData.rarity = rarity.getList();
|
||||
currentData.subTypes = subTypes.getList();
|
||||
currentData.cardTypes = cardTypes.getList();
|
||||
currentData.superTypes = superTypes.getList();
|
||||
currentData.manaCosts = manaCosts.getListAsInt();
|
||||
currentData.keyWords = keyWords.getList();
|
||||
currentData.colorType=colorType.getSelectedItem()==null?null:colorType.getSelectedItem().toString();
|
||||
currentData.cardText = cardText.getText().isEmpty()?null:cardText.getText();
|
||||
|
||||
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
|
||||
if (listeners != null && listeners.length > 0) {
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners) {
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
listenerList.add(ChangeListener.class, l);
|
||||
}
|
||||
public void setCurrentReward(RewardData data)
|
||||
{
|
||||
currentData=data;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
setEnabled(currentData!=null);
|
||||
if(currentData==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
updating=true;
|
||||
typeField.setSelectedItem(currentData.type);
|
||||
|
||||
probability.setValue(new Double(currentData.probability));
|
||||
count.setValue(currentData.count);
|
||||
addMaxCount.setValue(currentData.addMaxCount);
|
||||
cardName.setText(currentData.cardName);
|
||||
itemName.setText(currentData.itemName);
|
||||
editions.setText(currentData.editions);
|
||||
colors.setText(currentData.colors);
|
||||
rarity.setText(currentData.rarity);
|
||||
subTypes.setText(currentData.subTypes);
|
||||
cardTypes.setText(currentData.cardTypes);
|
||||
superTypes.setText(currentData.superTypes);
|
||||
manaCosts.setText(currentData.manaCosts);
|
||||
keyWords.setText(currentData.keyWords);
|
||||
colorType.setSelectedItem(currentData.colorType);
|
||||
cardText.setText(currentData.cardText);
|
||||
|
||||
|
||||
updating=false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.data.RewardData;
|
||||
|
||||
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 RewardsEditor extends JComponent{
|
||||
DefaultListModel<RewardData> model = new DefaultListModel<>();
|
||||
JList<RewardData> list = new JList<>(model);
|
||||
JToolBar toolBar = new JToolBar("toolbar");
|
||||
RewardEdit edit=new RewardEdit();
|
||||
|
||||
|
||||
|
||||
public class RewardDataRenderer 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 RewardData))
|
||||
return label;
|
||||
RewardData reward=(RewardData) value;
|
||||
StringBuilder builder=new StringBuilder();
|
||||
if(reward.type==null||reward.type.isEmpty())
|
||||
builder.append("Reward");
|
||||
else
|
||||
builder.append(reward.type);
|
||||
builder.append(" ");
|
||||
builder.append(reward.count);
|
||||
if(reward.addMaxCount>0)
|
||||
{
|
||||
builder.append("-");
|
||||
builder.append(reward.count+reward.addMaxCount);
|
||||
}
|
||||
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 RewardsEditor()
|
||||
{
|
||||
|
||||
list.setCellRenderer(new RewardsEditor.RewardDataRenderer());
|
||||
list.addListSelectionListener(e -> updateEdit());
|
||||
addButton("add",e->addReward());
|
||||
addButton("remove",e->remove());
|
||||
addButton("copy",e->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;
|
||||
RewardData data=new RewardData(model.get(selected));
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
|
||||
private void updateEdit() {
|
||||
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
edit.setCurrentReward(model.get(selected));
|
||||
}
|
||||
|
||||
void addReward()
|
||||
{
|
||||
RewardData data=new RewardData();
|
||||
model.add(model.size(),data);
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
int selected=list.getSelectedIndex();
|
||||
if(selected<0)
|
||||
return;
|
||||
model.remove(selected);
|
||||
}
|
||||
public void setRewards(RewardData[] rewards) {
|
||||
|
||||
model.clear();
|
||||
for (int i=0;i<rewards.length;i++) {
|
||||
model.add(i,rewards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public RewardData[] getRewards() {
|
||||
|
||||
RewardData[] rewards= new RewardData[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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static java.awt.Image.SCALE_FAST;
|
||||
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class SwingAtlas {
|
||||
|
||||
HashMap<String, ArrayList<ImageIcon>> images=new HashMap<>();
|
||||
public HashMap<String, ArrayList<ImageIcon>> getImages()
|
||||
{
|
||||
return images;
|
||||
}
|
||||
public SwingAtlas(FileHandle path)
|
||||
{
|
||||
if(!path.exists())
|
||||
return;
|
||||
TextureAtlas.TextureAtlasData data=new TextureAtlas.TextureAtlasData(path,path.parent(),false);
|
||||
for(TextureAtlas.TextureAtlasData.Region region: new Array.ArrayIterator<>(data.getRegions()))
|
||||
{
|
||||
String name=region.name;
|
||||
if(!images.containsKey(name))
|
||||
{
|
||||
images.put(name,new ArrayList<>());
|
||||
}
|
||||
ArrayList<ImageIcon> imageList=images.get(name);
|
||||
try {
|
||||
imageList.add(spriteToImage(region));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ImageIcon spriteToImage(TextureAtlas.TextureAtlasData.Region sprite) throws IOException {
|
||||
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));
|
||||
}
|
||||
|
||||
public ImageIcon get(String name) {
|
||||
return images.get(name).get(0);
|
||||
}
|
||||
|
||||
public boolean has(String name) {
|
||||
return images.containsKey(name);
|
||||
}
|
||||
|
||||
public ImageIcon getAny() {
|
||||
if(images.isEmpty())
|
||||
return null;
|
||||
ArrayList<ImageIcon> imageList= images.get(images.keySet().iterator().next());
|
||||
if(imageList.isEmpty())
|
||||
return null;
|
||||
return imageList.get(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.util.Config;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class SwingAtlasPreview extends Box {
|
||||
private String sprite="";
|
||||
Timer timer;
|
||||
public SwingAtlasPreview() {
|
||||
super(BoxLayout.Y_AXIS);
|
||||
|
||||
timer = new Timer(200, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
counter++;
|
||||
for (Pair<JLabel, ArrayList<ImageIcon>> element : labels) {
|
||||
element.getKey().setIcon(element.getValue().get(counter % element.getValue().size()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
int counter=0;
|
||||
List<Pair<JLabel,ArrayList<ImageIcon>>> labels=new ArrayList<>();
|
||||
public void setSpritePath(String sprite) {
|
||||
|
||||
removeAll();
|
||||
counter=0;
|
||||
labels.clear();
|
||||
if(this.sprite.equals(sprite))
|
||||
return;
|
||||
this.sprite=sprite;
|
||||
SwingAtlas atlas=new SwingAtlas(Config.instance().getFile(sprite));
|
||||
for(Map.Entry<String, ArrayList<ImageIcon>> element:atlas.getImages().entrySet())
|
||||
{
|
||||
JLabel image=new JLabel(element.getValue().get(0));
|
||||
add(new JLabel(element.getKey()));
|
||||
add(image);
|
||||
labels.add(Pair.of(image, element.getValue()));
|
||||
}
|
||||
timer.restart();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package forge.adventure.editor;
|
||||
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Editor class to edit configuration, maybe moved or removed
|
||||
*/
|
||||
public class TextListEdit extends Box {
|
||||
JTextField edit=new JTextField();
|
||||
JButton findButton=new JButton(UIManager.getIcon("add"));
|
||||
JComboBox elements;
|
||||
public TextListEdit(String[] possibleElements) {
|
||||
super(BoxLayout.X_AXIS);
|
||||
|
||||
findButton.addActionListener(e->find());
|
||||
|
||||
add(edit);
|
||||
//add(findButton);
|
||||
elements= new JComboBox(possibleElements);
|
||||
add(elements);
|
||||
|
||||
}
|
||||
public TextListEdit()
|
||||
{
|
||||
this(new String[0]);
|
||||
|
||||
}
|
||||
JTextField getEdit()
|
||||
{
|
||||
return edit;
|
||||
}
|
||||
|
||||
private void find() {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Config.instance().getFilePath("")));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
if (fc.showOpenDialog(this) ==
|
||||
JFileChooser.APPROVE_OPTION) {
|
||||
File selected = fc.getSelectedFile();
|
||||
|
||||
try {
|
||||
if (selected != null&&selected.getCanonicalPath().startsWith(new File(Config.instance().getFilePath("")).getCanonicalPath())) {
|
||||
edit.setText(selected.getCanonicalPath().substring(new File(Config.instance().getFilePath("")).getCanonicalPath().length()+1));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setText(String[] itemName) {
|
||||
if(itemName==null)
|
||||
edit.setText("");
|
||||
else
|
||||
edit.setText(String.join(";",itemName));
|
||||
}
|
||||
|
||||
public void setText(int[] intValues) {
|
||||
if(intValues==null)
|
||||
{
|
||||
edit.setText("");
|
||||
return;
|
||||
}
|
||||
StringBuilder values= new StringBuilder();
|
||||
for(int i=0;i<intValues.length;i++)
|
||||
{
|
||||
values.append(intValues[i]);
|
||||
if(intValues.length>i+2)
|
||||
values.append(";");
|
||||
}
|
||||
edit.setText(values.toString());
|
||||
}
|
||||
|
||||
public String[] getList() {
|
||||
return edit.getText().isEmpty()?null:edit.getText().split(";");
|
||||
}
|
||||
|
||||
public int[] getListAsInt() {
|
||||
if(edit.getText().isEmpty())
|
||||
return null;
|
||||
String[] stringList=getList();
|
||||
int[] retList=new int[stringList.length];
|
||||
for(int i=0;i<retList.length;i++)
|
||||
{
|
||||
String intName=stringList[i];
|
||||
try
|
||||
{
|
||||
retList[i] = Integer.valueOf(intName);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
retList[i] =0;
|
||||
}
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.FDeckEditor;
|
||||
import forge.gamemodes.quest.QuestMode;
|
||||
import forge.gamemodes.quest.QuestSpellShop;
|
||||
import forge.gamemodes.quest.data.DeckConstructionRules;
|
||||
import forge.gamemodes.quest.data.QuestData;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.ColumnDef;
|
||||
import forge.itemmanager.ItemColumn;
|
||||
import forge.itemmanager.ItemManagerConfig;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.FScreen;
|
||||
import forge.toolbox.FEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DeckEditScene
|
||||
* scene class that contains the Deck editor
|
||||
*/
|
||||
public class DeckEditScene extends ForgeScene {
|
||||
public class AdventureDeckEditor extends FDeckEditor {
|
||||
public AdventureDeckEditor(boolean commander) {
|
||||
super(commander ? EditorType.QuestCommander : EditorType.Quest, "", false, new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onActivate() {
|
||||
super.onActivate();
|
||||
QuestSpellShop.updateDecksForEachCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<ColumnDef, ItemColumn> getColOverrides(ItemManagerConfig config) {
|
||||
Map<ColumnDef, ItemColumn> colOverrides = new HashMap<>();
|
||||
switch (config) {
|
||||
case QUEST_EDITOR_POOL:
|
||||
ItemColumn.addColOverride(config, colOverrides, ColumnDef.NEW, FModel.getQuest().getCards().getFnNewCompare(), FModel.getQuest().getCards().getFnNewGet());
|
||||
break;
|
||||
case QUEST_DECK_EDITOR:
|
||||
ItemColumn.addColOverride(config, colOverrides, ColumnDef.NEW, FModel.getQuest().getCards().getFnNewCompare(), FModel.getQuest().getCards().getFnNewGet());
|
||||
ItemColumn.addColOverride(config, colOverrides, ColumnDef.DECKS, QuestSpellShop.fnDeckCompare, QuestSpellShop.fnDeckGet);
|
||||
break;
|
||||
default:
|
||||
colOverrides = null; //shouldn't happen
|
||||
break;
|
||||
}
|
||||
return colOverrides;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
for(TabPage page:tabPages)
|
||||
{
|
||||
if(page instanceof CardManagerPage)
|
||||
((CardManagerPage)page).refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdventureDeckEditor screen;
|
||||
Stage stage;
|
||||
|
||||
public DeckEditScene() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (stage != null)
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
QuestData data = new QuestData("", 0, QuestMode.Classic, null, false, "", DeckConstructionRules.Commander);
|
||||
FModel.getQuest().load(data);
|
||||
|
||||
|
||||
FModel.getQuest().getCards().getCardpool().clear();
|
||||
|
||||
|
||||
|
||||
for (PaperCard card : AdventurePlayer.current().getCards())
|
||||
FModel.getQuest().getCards().addSingleCard(card, 1);
|
||||
|
||||
|
||||
Deck deck = AdventurePlayer.current().getDeck();
|
||||
getScreen();
|
||||
screen.getEditorType().getController().setDeck(deck);
|
||||
screen.refresh();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
super.enter();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FScreen getScreen() {
|
||||
return screen==null?screen = new AdventureDeckEditor(false):screen;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.character.EnemySprite;
|
||||
import forge.adventure.character.PlayerSprite;
|
||||
import forge.assets.FSkin;
|
||||
import forge.screens.FScreen;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameRules;
|
||||
import forge.game.GameType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.gamemodes.match.HostedMatch;
|
||||
import forge.gui.interfaces.IGuiGame;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.trackable.TrackableCollection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* DuelScene
|
||||
* Forge screen scene that contains the duel screen
|
||||
*/
|
||||
public class DuelScene extends ForgeScene {
|
||||
|
||||
//GameLobby lobby;
|
||||
HostedMatch hostedMatch;
|
||||
EnemySprite enemy;
|
||||
PlayerSprite player;
|
||||
RegisteredPlayer humanPlayer;
|
||||
public DuelScene() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
|
||||
public void GameEnd() {
|
||||
Scene last= AdventureApplicationAdapter.instance.switchToLast();
|
||||
|
||||
if(last instanceof HudScene)
|
||||
{
|
||||
((HudScene)last).stage.setWinner(humanPlayer == hostedMatch.getGame().getMatch().getWinner());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
Set<GameType> appliedVariants = new HashSet<>();
|
||||
appliedVariants.add(GameType.Constructed);
|
||||
|
||||
List<RegisteredPlayer> players = new ArrayList<>();
|
||||
Deck playerDeck=(Deck)AdventurePlayer.current().getDeck().copyTo("PlayerDeckCopy");
|
||||
int missingCards= Config.instance().getConfigData().minDeckSize-playerDeck.getMain().countAll();
|
||||
if(missingCards>0)
|
||||
playerDeck.getMain().add("Wastes",missingCards);
|
||||
humanPlayer = RegisteredPlayer.forVariants(2, appliedVariants,playerDeck, null, false, null, null);
|
||||
LobbyPlayer playerObject = GamePlayerUtil.getGuiPlayer();
|
||||
FSkin.getAvatars().put(90001, Current.player().avatar());
|
||||
playerObject.setAvatarIndex(90001);
|
||||
humanPlayer.setPlayer(playerObject);
|
||||
humanPlayer.setStartingLife(Current.player().getLife());
|
||||
Current.setLatestDeck(enemy.getData().generateDeck());
|
||||
RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(2, appliedVariants, Current.latestDeck(), null, false, null, null);
|
||||
LobbyPlayer enemyPlayer = GamePlayerUtil.createAiPlayer();
|
||||
|
||||
FSkin.getAvatars().put(90000, this.enemy.getAvatar());
|
||||
enemyPlayer.setAvatarIndex(90000);
|
||||
|
||||
enemyPlayer.setName(this.enemy.getData().name);
|
||||
aiPlayer.setPlayer(enemyPlayer);
|
||||
aiPlayer.setStartingLife(Math.round((float)enemy.getData().life*Current.player().getDifficulty().enemyLifeFactor));
|
||||
|
||||
players.add(humanPlayer);
|
||||
players.add(aiPlayer);
|
||||
|
||||
final Map<RegisteredPlayer, IGuiGame> guiMap = new HashMap<>();
|
||||
guiMap.put(humanPlayer, MatchController.instance);
|
||||
|
||||
hostedMatch = MatchController.hostMatch();
|
||||
|
||||
|
||||
GameRules rules = new GameRules(GameType.Constructed);
|
||||
rules.setPlayForAnte(false);
|
||||
rules.setMatchAnteRarity(true);
|
||||
rules.setGamesPerMatch(1);
|
||||
rules.setManaBurn(false);
|
||||
|
||||
hostedMatch.setEndGameHook(() -> GameEnd());
|
||||
hostedMatch.startMatch(rules, appliedVariants, players, guiMap);
|
||||
|
||||
MatchController.instance.setGameView(hostedMatch.getGameView());
|
||||
|
||||
|
||||
for (final Player p : hostedMatch.getGame().getPlayers()) {
|
||||
if (p.getController() instanceof PlayerControllerHuman) {
|
||||
final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController();
|
||||
humanController.setGui(MatchController.instance);
|
||||
MatchController.instance.setOriginalGameController(p.getView(), humanController);
|
||||
MatchController.instance.openView(new TrackableCollection<>(p.getView()));
|
||||
}
|
||||
}
|
||||
super.enter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FScreen getScreen() {
|
||||
return MatchController.getView();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setEnemy(EnemySprite data) {
|
||||
this.enemy = data;
|
||||
}
|
||||
|
||||
public void setPlayer(PlayerSprite sprite) {
|
||||
this.player = sprite;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Input;
|
||||
import forge.Forge;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.toolbox.FContainer;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FGestureAdapter;
|
||||
import forge.toolbox.FOverlay;
|
||||
import forge.util.Utils;
|
||||
import forge.gui.error.BugReporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* ForgeInput
|
||||
* Handles input for forge screens
|
||||
*/
|
||||
public class ForgeInput extends FGestureAdapter {
|
||||
private static final List<FDisplayObject> potentialListeners = new ArrayList<>();
|
||||
private static char lastKeyTyped;
|
||||
private static boolean keyTyped, shiftKeyDown;
|
||||
private final ForgeScene forgeScene;
|
||||
private final Forge.KeyInputAdapter keyInputAdapter = null;
|
||||
//mouseMoved and scrolled events for desktop version
|
||||
private int mouseMovedX, mouseMovedY;
|
||||
|
||||
public ForgeInput(ForgeScene forgeScene) {
|
||||
this.forgeScene=forgeScene;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keyCode) {
|
||||
if (keyCode == Input.Keys.MENU) {
|
||||
//showMenu();
|
||||
return true;
|
||||
}
|
||||
if (keyCode == Input.Keys.SHIFT_LEFT || keyCode == Input.Keys.SHIFT_RIGHT) {
|
||||
shiftKeyDown = true;
|
||||
}
|
||||
|
||||
// Cursor keys emulate swipe gestures
|
||||
// First we touch the screen and later swipe (fling) in the direction of the key pressed
|
||||
if (keyCode == Input.Keys.LEFT) {
|
||||
touchDown(0, 0, 0, 0);
|
||||
return fling(1000, 0);
|
||||
}
|
||||
if (keyCode == Input.Keys.RIGHT) {
|
||||
touchDown(0, 0, 0, 0);
|
||||
return fling(-1000, 0);
|
||||
}
|
||||
if (keyCode == Input.Keys.UP) {
|
||||
touchDown(0, 0, 0, 0);
|
||||
return fling(0, -1000);
|
||||
}
|
||||
if (keyCode == Input.Keys.DOWN) {
|
||||
touchDown(0, 0, 0, 0);
|
||||
return fling(0, 1000);
|
||||
}
|
||||
/*
|
||||
if(keyCode == Input.Keys.BACK){
|
||||
if (destroyThis)
|
||||
deviceAdapter.exit();
|
||||
else if(onHomeScreen() && isLandscapeMode())
|
||||
back();
|
||||
}
|
||||
*/
|
||||
if (keyInputAdapter == null) {
|
||||
if (Forge.KeyInputAdapter.isModifierKey(keyCode)) {
|
||||
return false; //don't process modifiers keys for unknown adapter
|
||||
}
|
||||
//if no active key input adapter, give current screen or overlay a chance to handle key
|
||||
FContainer container = FOverlay.getTopOverlay();
|
||||
if (container == null) {
|
||||
container = MatchController.getView();
|
||||
if (container == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return container.keyDown(keyCode);
|
||||
}
|
||||
return keyInputAdapter.keyDown(keyCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keyCode) {
|
||||
keyTyped = false; //reset on keyUp
|
||||
if (keyCode == Input.Keys.SHIFT_LEFT || keyCode == Input.Keys.SHIFT_RIGHT) {
|
||||
shiftKeyDown = false;
|
||||
}
|
||||
if (keyInputAdapter != null) {
|
||||
return keyInputAdapter.keyUp(keyCode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(char ch) {
|
||||
if (keyInputAdapter != null) {
|
||||
if (ch >= ' ' && ch <= '~') { //only process this event if character is printable
|
||||
//prevent firing this event more than once for the same character on the same key down, otherwise it fires too often
|
||||
if (lastKeyTyped != ch || !keyTyped) {
|
||||
keyTyped = true;
|
||||
lastKeyTyped = ch;
|
||||
return keyInputAdapter.keyTyped(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePotentialListeners(int x, int y) {
|
||||
potentialListeners.clear();
|
||||
|
||||
//base potential listeners on object containing touch down point
|
||||
for (FOverlay overlay : FOverlay.getOverlaysTopDown()) {
|
||||
if (overlay.isVisibleOnScreen(forgeScene.getScreen())) {
|
||||
overlay.buildTouchListeners(x, y, potentialListeners);
|
||||
if (overlay.preventInputBehindOverlay()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
forgeScene.buildTouchListeners(x, y, potentialListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int x, int y, int pointer, int button) {
|
||||
if (pointer == 0) { //don't change listeners when second finger goes down for zoom
|
||||
updatePotentialListeners(x, y);
|
||||
if (keyInputAdapter != null) {
|
||||
if (!keyInputAdapter.allowTouchInput() || !potentialListeners.contains(keyInputAdapter.getOwner())) {
|
||||
//endKeyInput(); //end key input if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.touchDown(x, y, pointer, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean press(float x, float y) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.press(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release(float x, float y) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.release(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean longPress(float x, float y) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.longPress(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tap(float x, float y, int count) {
|
||||
if (shiftKeyDown && flick(x, y)) {
|
||||
return true; //give flick logic a chance to handle Shift+click
|
||||
}
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.tap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flick(float x, float y) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.flick(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fling(float velocityX, float velocityY) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.fling(velocityX, velocityY)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.pan(listener.screenToLocalX(x), listener.screenToLocalY(y), deltaX, deltaY, moreVertical)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean panStop(float x, float y) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.panStop(listener.screenToLocalX(x), listener.screenToLocalY(y))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean zoom(float x, float y, float amount) {
|
||||
try {
|
||||
for (FDisplayObject listener : potentialListeners) {
|
||||
if (listener.zoom(listener.screenToLocalX(x), listener.screenToLocalY(y), amount)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(int x, int y) {
|
||||
mouseMovedX = x;
|
||||
mouseMovedY = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrolled(float amountX, float amountY) {
|
||||
updatePotentialListeners(mouseMovedX, mouseMovedY);
|
||||
|
||||
if (Forge.KeyInputAdapter.isCtrlKeyDown()) { //zoom in or out based on amount
|
||||
return zoom(mouseMovedX, mouseMovedY, -Utils.AVG_FINGER_WIDTH * amountY);
|
||||
}
|
||||
|
||||
boolean handled;
|
||||
if (Forge.KeyInputAdapter.isShiftKeyDown()) {
|
||||
handled = pan(mouseMovedX, mouseMovedY, -Utils.AVG_FINGER_WIDTH * amountX, 0, false);
|
||||
} else {
|
||||
handled = pan(mouseMovedX, mouseMovedY, 0, -Utils.AVG_FINGER_HEIGHT * amountY, true);
|
||||
}
|
||||
if (panStop(mouseMovedX, mouseMovedY)) {
|
||||
handled = true;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.ImageCache;
|
||||
import forge.screens.FScreen;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FOverlay;
|
||||
import forge.gamemodes.match.LobbySlotType;
|
||||
import forge.interfaces.IUpdateable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* base class to render base forge screens like the deck editor and matches
|
||||
*/
|
||||
public abstract class ForgeScene extends Scene implements IUpdateable {
|
||||
|
||||
//GameLobby lobby;
|
||||
Graphics localGraphics;
|
||||
ForgeInput input=new ForgeInput(this);
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
@Override
|
||||
public void render() {
|
||||
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear the screen.
|
||||
if (getScreen() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
localGraphics.begin(AdventureApplicationAdapter.instance.getCurrentWidth(), AdventureApplicationAdapter.instance.getCurrentHeight());
|
||||
getScreen().screenPos.setSize(AdventureApplicationAdapter.instance.getCurrentWidth(), AdventureApplicationAdapter.instance.getCurrentHeight());
|
||||
if (getScreen().getRotate180()) {
|
||||
localGraphics.startRotateTransform(AdventureApplicationAdapter.instance.getCurrentWidth() / 2f, AdventureApplicationAdapter.instance.getCurrentHeight() / 2f, 180);
|
||||
}
|
||||
getScreen().draw(localGraphics);
|
||||
if (getScreen().getRotate180()) {
|
||||
localGraphics.endTransform();
|
||||
}
|
||||
for (FOverlay overlay : FOverlay.getOverlays()) {
|
||||
if (overlay.isVisibleOnScreen(getScreen())) {
|
||||
overlay.screenPos.setSize(AdventureApplicationAdapter.instance.getCurrentWidth(), AdventureApplicationAdapter.instance.getCurrentHeight());
|
||||
overlay.setSize(AdventureApplicationAdapter.instance.getCurrentWidth(), AdventureApplicationAdapter.instance.getCurrentHeight()); //update overlay sizes as they're rendered
|
||||
if (overlay.getRotate180()) {
|
||||
localGraphics.startRotateTransform(AdventureApplicationAdapter.instance.getCurrentHeight() / 2f, AdventureApplicationAdapter.instance.getCurrentHeight() / 2f, 180);
|
||||
}
|
||||
overlay.draw(localGraphics);
|
||||
if (overlay.getRotate180()) {
|
||||
localGraphics.endTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
localGraphics.end();
|
||||
|
||||
//Batch.end();
|
||||
}
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
|
||||
ImageCache.allowSingleLoad();
|
||||
ForgeAnimation.advanceAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
if(getScreen()!=null)
|
||||
getScreen().setSize(AdventureApplicationAdapter.instance.getCurrentWidth(), AdventureApplicationAdapter.instance.getCurrentHeight());
|
||||
|
||||
Forge.openScreen(getScreen());
|
||||
Gdx.input.setInputProcessor(input);
|
||||
|
||||
}
|
||||
public abstract FScreen getScreen();
|
||||
|
||||
public void buildTouchListeners(int x, int y, List<FDisplayObject> potentialListeners) {
|
||||
if(getScreen()!=null)
|
||||
getScreen().buildTouchListeners(x, y, potentialListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
localGraphics = AdventureApplicationAdapter.instance.getGraphics();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(boolean fullUpdate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int slot, LobbySlotType type) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import forge.adventure.stage.WorldStage;
|
||||
|
||||
/**
|
||||
* Game scene main over world scene
|
||||
* does render the WorldStage and HUD
|
||||
*/
|
||||
public class GameScene extends HudScene {
|
||||
|
||||
public GameScene() {
|
||||
super(WorldStage.getInstance());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
|
||||
stage.act(delta);
|
||||
|
||||
|
||||
}
|
||||
@Override
|
||||
public void render() {
|
||||
|
||||
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.draw();
|
||||
hud.draw();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.stage.GameStage;
|
||||
|
||||
/**
|
||||
* Hud base scene
|
||||
*/
|
||||
public class HudScene extends Scene implements InputProcessor {
|
||||
|
||||
GameHUD hud;
|
||||
GameStage stage;
|
||||
|
||||
protected HudScene(GameStage s) {
|
||||
stage = s;
|
||||
hud = GameHUD.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean leave() {
|
||||
stage.leave();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
Gdx.input.setInputProcessor(this);
|
||||
stage.enter();
|
||||
hud.enter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta)
|
||||
{
|
||||
stage.act(delta);
|
||||
hud.act(delta);
|
||||
}
|
||||
@Override
|
||||
public void render() {
|
||||
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.draw();
|
||||
hud.draw();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode) {
|
||||
|
||||
if (hud.keyDown(keycode))
|
||||
return true;
|
||||
return stage.keyDown(keycode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keycode) {
|
||||
|
||||
if (hud.keyUp(keycode))
|
||||
return true;
|
||||
return stage.keyUp(keycode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(char character) {
|
||||
|
||||
if (hud.keyTyped(character))
|
||||
return true;
|
||||
return stage.keyTyped(character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
|
||||
if (hud.touchDown(screenX, screenY, pointer, button))
|
||||
return true;
|
||||
return stage.touchDown(screenX, screenY, pointer, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
|
||||
if (hud.touchUp(screenX, screenY, pointer, button))
|
||||
return true;
|
||||
return stage.touchUp(screenX, screenY, pointer, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDragged(int screenX, int screenY, int pointer) {
|
||||
if (hud.touchDragged(screenX, screenY, pointer))
|
||||
return true;
|
||||
return stage.touchDragged(screenX, screenY, pointer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(int screenX, int screenY) {
|
||||
if (hud.mouseMoved(screenX, screenY))
|
||||
return true;
|
||||
return stage.mouseMoved(screenX, screenY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrolled(float amountX, float amountY) {
|
||||
if (hud.scrolled(amountX, amountY))
|
||||
return true;
|
||||
return stage.scrolled(amountX, amountY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.util.Current;
|
||||
|
||||
/**
|
||||
* Scene for the Inn in towns
|
||||
*
|
||||
*/
|
||||
public class InnScene extends UIScene {
|
||||
|
||||
public InnScene()
|
||||
{
|
||||
super("ui/inn.json");
|
||||
}
|
||||
|
||||
public void done()
|
||||
{
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
public void heal()
|
||||
{
|
||||
Current.player().heal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
|
||||
stage.act(delta);
|
||||
}
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
ui.onButtonPress("done",()->done());
|
||||
ui.onButtonPress("heal",()->heal());
|
||||
TextButton doneButton = ui.findActor("done");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.data.DifficultyData;
|
||||
import forge.adventure.data.HeroListData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Selector;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.deck.Deck;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.util.NameGenerator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* NewGame scene that contains the character creation
|
||||
*/
|
||||
public class NewGameScene extends UIScene {
|
||||
TextField selectedName;
|
||||
Deck[] starterDeck;
|
||||
private Image avatarImage;
|
||||
private int avatarIndex = 0;
|
||||
private Selector race;
|
||||
private Selector deck;
|
||||
private Selector gender;
|
||||
private Selector difficulty;
|
||||
|
||||
public NewGameScene() {
|
||||
super("ui/new_game.json");
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
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()],0);
|
||||
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
|
||||
//image = new Texture(img);
|
||||
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.GameScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean back() {
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.StartScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
selectedName = ui.findActor("nameField");
|
||||
selectedName.setText(NameGenerator.getRandomName("Any", "Any", ""));
|
||||
avatarImage = ui.findActor("avatarPreview");
|
||||
gender = ui.findActor("gender");
|
||||
gender.setTextList(new String[]{"Male", "Female"});
|
||||
gender.addListener(event -> updateAvatar());
|
||||
Random rand=new Random();
|
||||
|
||||
deck = ui.findActor("deck");
|
||||
|
||||
starterDeck = Config.instance().starterDecks();
|
||||
Array<String> stringList = new Array<>(starterDeck.length);
|
||||
for (Deck deck : starterDeck)
|
||||
stringList.add(deck.getName());
|
||||
|
||||
deck.setTextList(stringList);
|
||||
|
||||
race = ui.findActor("race");
|
||||
race.addListener(event -> updateAvatar());
|
||||
race.setTextList(HeroListData.getRaces());
|
||||
difficulty = ui.findActor("difficulty");
|
||||
|
||||
Array<String> diffList = new Array<>(starterDeck.length);
|
||||
int i=0;
|
||||
int startingDifficulty=0;
|
||||
for (DifficultyData diff : Config.instance().getConfigData().difficulties)
|
||||
{
|
||||
if(diff.startingDifficulty)
|
||||
startingDifficulty=i;
|
||||
diffList.add(diff.name);
|
||||
i++;
|
||||
}
|
||||
difficulty.setTextList(diffList);
|
||||
difficulty.setCurrentIndex(startingDifficulty);
|
||||
avatarIndex=rand.nextInt();
|
||||
gender.setCurrentIndex(rand.nextInt());
|
||||
deck.setCurrentIndex(rand.nextInt());
|
||||
race.setCurrentIndex(rand.nextInt());
|
||||
ui.onButtonPress("back", this::back);
|
||||
ui.onButtonPress("start", this::start);
|
||||
ui.onButtonPress("leftAvatar", this::leftAvatar);
|
||||
ui.onButtonPress("rightAvatar", this::rightAvatar);
|
||||
|
||||
updateAvatar();
|
||||
}
|
||||
|
||||
private void rightAvatar() {
|
||||
|
||||
avatarIndex++;
|
||||
updateAvatar();
|
||||
}
|
||||
|
||||
private void leftAvatar() {
|
||||
avatarIndex--;
|
||||
updateAvatar();
|
||||
}
|
||||
|
||||
private boolean updateAvatar() {
|
||||
|
||||
avatarImage.setDrawable(new TextureRegionDrawable(HeroListData.getAvatar(race.getCurrentIndex(), gender.getCurrentIndex() != 0, avatarIndex)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.character.ShopActor;
|
||||
import forge.assets.ImageCache;
|
||||
import forge.adventure.util.CardUtil;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.Reward;
|
||||
import forge.adventure.util.RewardActor;
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
import forge.adventure.world.PointOfInterestChanges;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
/**
|
||||
* Displays the rewards of a fight or a treasure
|
||||
*/
|
||||
public class RewardScene extends UIScene {
|
||||
|
||||
private TextButton doneButton;
|
||||
|
||||
public enum Type
|
||||
{
|
||||
Shop,
|
||||
Loot
|
||||
|
||||
}
|
||||
Type type;
|
||||
Array<Actor> generated =new Array<>();
|
||||
static public final float CARD_WIDTH =550f;
|
||||
static public final float CARD_HEIGHT =400f;
|
||||
static public final float CARD_WIDTH_TO_HEIGHT =CARD_WIDTH/CARD_HEIGHT;
|
||||
public RewardScene()
|
||||
{
|
||||
super("ui/items.json");
|
||||
}
|
||||
|
||||
boolean doneClicked=false;
|
||||
float flipCountDown=1.0f;
|
||||
public boolean done()
|
||||
{
|
||||
if(doneClicked)
|
||||
return true;
|
||||
|
||||
if(type==Type.Loot)
|
||||
{
|
||||
|
||||
boolean wait=false;
|
||||
for(Actor actor: new Array.ArrayIterator<>(generated))
|
||||
{
|
||||
if(!(actor instanceof RewardActor))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
RewardActor reward=(RewardActor) actor;
|
||||
AdventurePlayer.current().addReward(reward.getReward());
|
||||
if(!reward.isFlipped())
|
||||
{
|
||||
wait = true;
|
||||
reward.flip();
|
||||
}
|
||||
}
|
||||
if(wait)
|
||||
{
|
||||
flipCountDown=3.0f;
|
||||
doneClicked=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
|
||||
stage.act(delta);
|
||||
ImageCache.allowSingleLoad();
|
||||
if(doneClicked)
|
||||
{
|
||||
if(type==Type.Loot)
|
||||
flipCountDown-=Gdx.graphics.getDeltaTime();
|
||||
if(flipCountDown<=0)
|
||||
{
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
ui.onButtonPress("done",()->done());
|
||||
doneButton=ui.findActor("done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void loadRewards(Array<Reward> newRewards, Type type, ShopActor shopActor)
|
||||
{
|
||||
this.type=type;
|
||||
doneClicked=false;
|
||||
|
||||
|
||||
|
||||
|
||||
for(Actor actor: new Array.ArrayIterator<>(generated))
|
||||
{
|
||||
actor.remove();
|
||||
if(actor instanceof RewardActor)
|
||||
{
|
||||
((RewardActor)actor).dispose();
|
||||
}
|
||||
}
|
||||
generated.clear();
|
||||
|
||||
|
||||
Actor card=ui.findActor("cards");
|
||||
|
||||
// card.setDrawable(new TextureRegionDrawable(new Texture(Res.CurrentRes.GetFile("ui/transition.png"))));
|
||||
|
||||
float targetWidth = card.getWidth();
|
||||
float targetHeight = card.getHeight();
|
||||
float xOff = card.getX();
|
||||
float yOff = card.getY();
|
||||
|
||||
int numberOfRows=0;
|
||||
float cardWidth=0;
|
||||
float cardHeight=0;
|
||||
float bestCardHeight=0;
|
||||
int numberOfColumns=0;
|
||||
float targetArea=targetHeight*targetWidth;
|
||||
float oldCardArea=0;
|
||||
float newArea=0;
|
||||
|
||||
switch (type) {
|
||||
case Shop:
|
||||
doneButton.setText("Return");
|
||||
break;
|
||||
case Loot:
|
||||
doneButton.setText("Take all");
|
||||
break;
|
||||
}
|
||||
for(int h=1;h<targetHeight;h++)
|
||||
{
|
||||
cardHeight=h;
|
||||
if(type==Type.Shop)
|
||||
{
|
||||
cardHeight+=doneButton.getHeight();
|
||||
}
|
||||
//cardHeight=targetHeight/i;
|
||||
cardWidth=h/ CARD_WIDTH_TO_HEIGHT;
|
||||
newArea=newRewards.size*cardWidth*cardHeight;
|
||||
int rows=(int) (targetHeight/cardHeight);
|
||||
int cols =(int)Math.ceil(newRewards.size/(double)rows);
|
||||
if(newArea>oldCardArea&&newArea<=targetArea&&rows*cardHeight<targetHeight&&cols*cardWidth<targetWidth)
|
||||
{
|
||||
oldCardArea=newArea;
|
||||
numberOfRows= rows;
|
||||
numberOfColumns =cols;
|
||||
bestCardHeight=h;
|
||||
}
|
||||
}
|
||||
|
||||
cardHeight=bestCardHeight;
|
||||
cardWidth=bestCardHeight/ CARD_WIDTH_TO_HEIGHT;
|
||||
|
||||
yOff+=(targetHeight-(cardHeight*numberOfRows))/2f;
|
||||
xOff+=(targetWidth-(cardWidth*numberOfColumns))/2f;
|
||||
float spacing=2;
|
||||
int i=0;
|
||||
for(Reward reward:new Array.ArrayIterator<>(newRewards))
|
||||
{
|
||||
boolean skipCard=false;
|
||||
if(type==Type.Shop)
|
||||
{
|
||||
if(shopActor.getMapStage().getChanges().wasCardBought(shopActor.getObjectID(),i))
|
||||
{
|
||||
skipCard=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int currentRow=(i/numberOfColumns);
|
||||
float lastRowXAdjust=0;
|
||||
if(currentRow==numberOfRows-1)
|
||||
{
|
||||
int lastRowCount=newRewards.size%numberOfColumns;
|
||||
if(lastRowCount!=0)
|
||||
lastRowXAdjust=((numberOfColumns*cardWidth)-(lastRowCount*cardWidth))/2;
|
||||
}
|
||||
RewardActor actor=new RewardActor(reward,type==Type.Loot);
|
||||
actor.setBounds(lastRowXAdjust+xOff+cardWidth*(i%numberOfColumns)+spacing,yOff+cardHeight*currentRow+spacing,cardWidth-spacing*2,cardHeight-spacing*2);
|
||||
|
||||
if(type==Type.Shop)
|
||||
{
|
||||
if(currentRow!=((i+1)/numberOfColumns))
|
||||
yOff+=doneButton.getHeight();
|
||||
|
||||
TextButton buyCardButton=new BuyButton(shopActor.getObjectID(),i,shopActor.getMapStage().getChanges(),actor,doneButton);
|
||||
|
||||
generated.add(buyCardButton);
|
||||
if(!skipCard)
|
||||
{
|
||||
stage.addActor(buyCardButton);
|
||||
}
|
||||
}
|
||||
generated.add(actor);
|
||||
if(!skipCard)
|
||||
{
|
||||
stage.addActor(actor);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
updateBuyButtons();
|
||||
|
||||
}
|
||||
|
||||
private void updateBuyButtons() {
|
||||
|
||||
for(Actor actor: new Array.ArrayIterator<>(generated))
|
||||
{
|
||||
if(actor instanceof BuyButton)
|
||||
{
|
||||
((BuyButton)actor).update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class BuyButton extends TextButton {
|
||||
private final int objectID;
|
||||
private final int index;
|
||||
private final PointOfInterestChanges changes;
|
||||
RewardActor reward;
|
||||
int price;
|
||||
void update(){
|
||||
setDisabled(WorldSave.getCurrentSave().getPlayer().getGold()< price);
|
||||
}
|
||||
public BuyButton(int id, int i, PointOfInterestChanges ch, RewardActor actor, TextButton style) {
|
||||
super("",style.getStyle());
|
||||
this.objectID = id;
|
||||
this.index = i;
|
||||
this.changes = ch;
|
||||
reward=actor;
|
||||
setHeight(style.getHeight());
|
||||
setWidth(actor.getWidth());
|
||||
setX(actor.getX());
|
||||
setY(actor.getY()-getHeight());
|
||||
price= CardUtil.getCardPrice(actor.getReward().getCard());
|
||||
setText("Buy for "+price);
|
||||
addListener(new ClickListener(){
|
||||
|
||||
@Override
|
||||
public void clicked (InputEvent event, float x, float y) {
|
||||
if(Current.player().getGold()>= price)
|
||||
{
|
||||
changes.buyCard(objectID,index);
|
||||
Current.player().takeGold(price);
|
||||
Current.player().addReward(reward.getReward());
|
||||
setDisabled(true);
|
||||
reward.flip();
|
||||
remove();
|
||||
updateBuyButtons();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
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.Align;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.adventure.world.WorldSaveHeader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
/**
|
||||
* Scene to load and save the game.
|
||||
*
|
||||
*/
|
||||
public class SaveLoadScene extends UIScene {
|
||||
private final IntMap<TextButton> buttons = new IntMap<>();
|
||||
IntMap<WorldSaveHeader> previews = new IntMap<>();
|
||||
Color defColor;
|
||||
Table layout;
|
||||
boolean save = true;
|
||||
Dialog dialog;
|
||||
TextField textInput;
|
||||
Label header;
|
||||
int currentSlot = -3;
|
||||
Image previewImage;
|
||||
TextButton saveLoadButton;
|
||||
|
||||
public SaveLoadScene() {
|
||||
super("ui/save_load.json");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void addSaveSlot(String name, int i) {
|
||||
layout.add(Controls.newLabel(name));
|
||||
TextButton button = Controls.newTextButton("...");
|
||||
button.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
try {
|
||||
select(i);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
layout.add(button).expandX();
|
||||
buttons.put(i, button);
|
||||
layout.row();
|
||||
|
||||
}
|
||||
|
||||
public void back() {
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
}
|
||||
|
||||
public boolean select(int slot) {
|
||||
currentSlot = slot;
|
||||
|
||||
if (previews.containsKey(slot)) {
|
||||
WorldSaveHeader header = previews.get(slot);
|
||||
if (header.preview != null) {
|
||||
previewImage.setDrawable(new TextureRegionDrawable(new Texture(header.preview)));
|
||||
previewImage.layout();
|
||||
}
|
||||
}
|
||||
for (IntMap.Entry<TextButton> butt : new IntMap.Entries<TextButton> (buttons)) {
|
||||
butt.value.setColor(defColor);
|
||||
}
|
||||
if (buttons.containsKey(slot)) {
|
||||
TextButton button = buttons.get(slot);
|
||||
button.setColor(Color.RED);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void loadSave() {
|
||||
if (save) {
|
||||
textInput.setText("Save Game " + currentSlot);
|
||||
dialog.show(stage);
|
||||
stage.setKeyboardFocus(textInput);
|
||||
} else {
|
||||
if(WorldSave.load(currentSlot))
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.GameScene.instance);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveAbort() {
|
||||
|
||||
dialog.hide();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
dialog.hide();
|
||||
if( WorldSave.getCurrentSave().save(textInput.getText(), currentSlot))
|
||||
{
|
||||
updateFiles();
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.GameScene.instance);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void updateFiles() {
|
||||
|
||||
File f = new File(WorldSave.getSaveDir());
|
||||
f.mkdirs();
|
||||
File[] names = f.listFiles();
|
||||
if(names==null)
|
||||
throw new RuntimeException("Can not find save directory");
|
||||
previews.clear();
|
||||
for (File name : names) {
|
||||
if (WorldSave.isSafeFile(name.getName())) {
|
||||
try {
|
||||
|
||||
try (FileInputStream fos = new FileInputStream(name.getAbsolutePath());
|
||||
InflaterInputStream inf = new InflaterInputStream(fos);
|
||||
ObjectInputStream oos = new ObjectInputStream(inf)) {
|
||||
|
||||
|
||||
int slot=WorldSave.filenameToSlot(name.getName());
|
||||
WorldSaveHeader header = (WorldSaveHeader) oos.readObject();
|
||||
buttons.get(slot).setText(header.name);
|
||||
previews.put(slot, header);
|
||||
}
|
||||
|
||||
} catch (ClassNotFoundException | IOException | GdxRuntimeException e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setSaveGame(boolean save) {
|
||||
if (save) {
|
||||
header.setText("Save game");
|
||||
saveLoadButton.setText("Save");
|
||||
} else {
|
||||
header.setText("Load game");
|
||||
saveLoadButton.setText("Load");
|
||||
}
|
||||
this.save = save;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
select(-3);
|
||||
updateFiles();
|
||||
super.enter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
layout = new Table();
|
||||
layout.setFillParent(true);
|
||||
stage.addActor(layout);
|
||||
dialog = Controls.newDialog("Save");
|
||||
textInput = Controls.newTextField("");
|
||||
dialog.getButtonTable().add(Controls.newLabel("Name your new save file.")).colspan(2);
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newLabel("Name:")).align(Align.left);
|
||||
dialog.getButtonTable().add(textInput).fillX().expandX();
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newTextButton("Save", () -> save())).align(Align.left);
|
||||
dialog.getButtonTable().add(Controls.newTextButton("Abort", () -> saveAbort())).align(Align.left);
|
||||
|
||||
previewImage = ui.findActor("preview");
|
||||
header = Controls.newLabel("Save");
|
||||
header.setHeight(header.getHeight() * 2);
|
||||
layout.add(header).colspan(2).align(Align.center);
|
||||
layout.row();
|
||||
addSaveSlot("Auto save", -2);
|
||||
addSaveSlot("Quick save", -1);
|
||||
for (int i = 1; i < 11; i++)
|
||||
addSaveSlot("Slot:" + i, i);
|
||||
|
||||
saveLoadButton = ui.findActor("save");
|
||||
ui.onButtonPress("save",()-> loadSave());
|
||||
ui.onButtonPress("return",()-> back());
|
||||
defColor = saveLoadButton.getColor();
|
||||
|
||||
|
||||
ScrollPane scrollPane = ui.findActor("saveSlots");
|
||||
scrollPane.setActor(layout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
/**
|
||||
* Base class for all rendered scenes
|
||||
*/
|
||||
public abstract class Scene implements Disposable {
|
||||
|
||||
public Scene() {
|
||||
|
||||
}
|
||||
|
||||
public static int GetIntendedWidth() {
|
||||
return Config.instance().getConfigData().screenWidth;
|
||||
}
|
||||
|
||||
public static int GetIntendedHeight() {
|
||||
return Config.instance().getConfigData().screenHeight;
|
||||
}
|
||||
|
||||
public abstract void act(float delta);
|
||||
public abstract void render();
|
||||
|
||||
public void create() {
|
||||
|
||||
}
|
||||
|
||||
public Drawable DrawableImage(String path) {
|
||||
return new TextureRegionDrawable(new Texture(Config.instance().getFile(path)));
|
||||
}
|
||||
|
||||
public void resLoaded() {
|
||||
}
|
||||
|
||||
public boolean leave() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void enter() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
/**
|
||||
* Enum of all scenes
|
||||
*/
|
||||
public enum SceneType {
|
||||
StartScene(new forge.adventure.scene.StartScene()),
|
||||
NewGameScene(new forge.adventure.scene.NewGameScene()),
|
||||
SettingsScene(new forge.adventure.scene.SettingsScene()),
|
||||
GameScene(new forge.adventure.scene.GameScene()),
|
||||
DuelScene(new forge.adventure.scene.DuelScene()),
|
||||
SaveLoadScene(new forge.adventure.scene.SaveLoadScene()),
|
||||
DeckEditScene(new forge.adventure.scene.DeckEditScene()),
|
||||
TileMapScene(new forge.adventure.scene.TileMapScene()),
|
||||
RewardScene(new forge.adventure.scene.RewardScene()),
|
||||
InnScene(new forge.adventure.scene.InnScene());
|
||||
|
||||
|
||||
public final forge.adventure.scene.Scene instance;
|
||||
SceneType(forge.adventure.scene.Scene scene) {
|
||||
this.instance = scene;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.util.Localizer;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Scene to handle settings of the base forge and adventure mode
|
||||
*/
|
||||
public class SettingsScene extends UIScene {
|
||||
|
||||
|
||||
static public ForgePreferences Preference;
|
||||
Stage stage;
|
||||
Texture Background;
|
||||
private Table settingGroup;
|
||||
|
||||
public SettingsScene() {
|
||||
super("ui/settings.json");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (stage != null)
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
public void renderAct(float delta) {
|
||||
|
||||
|
||||
Gdx.gl.glClearColor(1, 0, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.getBatch().begin();
|
||||
stage.getBatch().disableBlending();
|
||||
stage.getBatch().draw(Background, 0, 0, GetIntendedWidth(), GetIntendedHeight());
|
||||
stage.getBatch().enableBlending();
|
||||
stage.getBatch().end();
|
||||
stage.act(delta);
|
||||
stage.draw();
|
||||
|
||||
}
|
||||
|
||||
public boolean back() {
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
return true;
|
||||
}
|
||||
private void addCheckBox(String name, ForgePreferences.FPref pref) {
|
||||
|
||||
|
||||
CheckBox box = Controls.newCheckBox("");
|
||||
box.setChecked(Preference.getPrefBoolean(pref));
|
||||
box.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Preference.setPref(pref, ((CheckBox) actor).isChecked());
|
||||
Preference.save();
|
||||
}
|
||||
});
|
||||
|
||||
addLabel(name);
|
||||
settingGroup.add(box).align(Align.right);
|
||||
}
|
||||
private void addSettingSlider(String name, ForgePreferences.FPref pref, int min,int max) {
|
||||
|
||||
Slider slide = Controls.newSlider(min,max, 1, false);
|
||||
slide.setValue(Preference.getPrefInt(pref));
|
||||
slide.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Preference.setPref(pref, String.valueOf((int) ((Slider) actor).getValue()));
|
||||
Preference.save();
|
||||
}
|
||||
});
|
||||
addLabel(name);
|
||||
settingGroup.add(slide).align(Align.right);
|
||||
}
|
||||
private void addSettingField(String name, boolean value, ChangeListener change) {
|
||||
|
||||
CheckBox box = Controls.newCheckBox("");
|
||||
box.setChecked(value);
|
||||
box.addListener(change);
|
||||
addLabel(name);
|
||||
settingGroup.add(box).align(Align.right);
|
||||
}
|
||||
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.addListener(change);
|
||||
|
||||
|
||||
addLabel(name);
|
||||
settingGroup.add(text).align(Align.right);
|
||||
}
|
||||
void addLabel( String name)
|
||||
{
|
||||
|
||||
Label label = new Label(name, Controls.GetSkin().get("white",Label.LabelStyle.class));
|
||||
|
||||
settingGroup.row().space(5);
|
||||
settingGroup.add(label).align(Align.left).fillX();
|
||||
}
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
settingGroup = new Table();
|
||||
if (Preference == null) {
|
||||
Preference = new ForgePreferences();
|
||||
}
|
||||
Localizer localizer = Localizer.getInstance();
|
||||
|
||||
SelectBox plane = Controls.newComboBox(Config.instance().getAllAdventures(), Config.instance().getSettingData().plane, new Function<Object, Void>() {
|
||||
@Override
|
||||
public Void apply(Object o) {
|
||||
Config.instance().getSettingData().plane= (String) o;
|
||||
Config.instance().saveSettings();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
addLabel("Plane");
|
||||
settingGroup.add(plane).align(Align.right);
|
||||
|
||||
|
||||
|
||||
addSettingField("Fullscreen", Config.instance().getSettingData().fullScreen, new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Config.instance().getSettingData().fullScreen=((CheckBox) actor).isChecked();
|
||||
Config.instance().saveSettings();
|
||||
}
|
||||
});
|
||||
addSettingField("Screen width", Config.instance().getSettingData().width, new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
String text=((TextField) actor).getText();
|
||||
Config.instance().getSettingData().width=text==null||text.isEmpty()?0:Integer.valueOf(text);
|
||||
Config.instance().saveSettings();
|
||||
}
|
||||
});
|
||||
addSettingField("Screen height", Config.instance().getSettingData().height, new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
String text=((TextField) actor).getText();
|
||||
Config.instance().getSettingData().height=text==null||text.isEmpty()?0:Integer.valueOf(text);
|
||||
Config.instance().saveSettings();
|
||||
}
|
||||
});
|
||||
addCheckBox(localizer.getMessage("lblCardName"), ForgePreferences.FPref.UI_OVERLAY_CARD_NAME);
|
||||
addSettingSlider(localizer.getMessage("cbAdjustMusicVolume"), ForgePreferences.FPref.UI_VOL_MUSIC,0,100);
|
||||
addSettingSlider(localizer.getMessage("cbAdjustSoundsVolume"), ForgePreferences.FPref.UI_VOL_SOUNDS, 0,100);
|
||||
addCheckBox(localizer.getMessage("lblManaCost"), ForgePreferences.FPref.UI_OVERLAY_CARD_MANA_COST);
|
||||
addCheckBox(localizer.getMessage("lblPowerOrToughness"), ForgePreferences.FPref.UI_OVERLAY_CARD_POWER);
|
||||
addCheckBox(localizer.getMessage("lblCardID"), ForgePreferences.FPref.UI_OVERLAY_CARD_ID);
|
||||
addCheckBox(localizer.getMessage("lblAbilityIcon"), ForgePreferences.FPref.UI_OVERLAY_ABILITY_ICONS);
|
||||
addCheckBox(localizer.getMessage("cbImageFetcher"), ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER);
|
||||
|
||||
|
||||
settingGroup.row();
|
||||
ui.onButtonPress("return", () -> back());
|
||||
|
||||
ScrollPane scrollPane = ui.findActor("settings");
|
||||
scrollPane.setActor(settingGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
}
|
||||
|
||||
enum ControlTypes {
|
||||
CheckBox,
|
||||
Slider,
|
||||
Resolution
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
/**
|
||||
* First scene after the splash screen
|
||||
*/
|
||||
public class StartScene extends UIScene {
|
||||
|
||||
Actor saveButton;
|
||||
Actor resumeButton;
|
||||
|
||||
public StartScene()
|
||||
{
|
||||
super("ui/start_menu.json");
|
||||
|
||||
}
|
||||
|
||||
public boolean NewGame() {
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.NewGameScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Save() {
|
||||
((SaveLoadScene) SceneType.SaveLoadScene.instance).setSaveGame(true);
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.SaveLoadScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Load() {
|
||||
((SaveLoadScene) SceneType.SaveLoadScene.instance).setSaveGame(false);
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.SaveLoadScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Resume() {
|
||||
AdventureApplicationAdapter.instance.switchToLast();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean settings() {
|
||||
AdventureApplicationAdapter.instance.switchScene(forge.adventure.scene.SceneType.SettingsScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Exit() {
|
||||
Gdx.app.exit();
|
||||
System.exit(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
|
||||
|
||||
saveButton.setVisible(WorldSave.getCurrentSave().getWorld().getData() != null);
|
||||
resumeButton.setVisible(WorldSave.getCurrentSave().getWorld().getData() != null);
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
|
||||
ui.onButtonPress("Start", () -> NewGame());
|
||||
ui.onButtonPress("Load", () -> Load());
|
||||
ui.onButtonPress("Start", () -> NewGame());
|
||||
ui.onButtonPress("Save", () -> Save());
|
||||
ui.onButtonPress("Resume", () -> Resume());
|
||||
|
||||
saveButton = ui.findActor("Save");
|
||||
resumeButton = ui.findActor("Resume");
|
||||
ui.onButtonPress("Settings", () -> settings());
|
||||
ui.onButtonPress("Exit", () -> Exit());
|
||||
saveButton.setVisible(false);
|
||||
resumeButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.stage.PointOfInterestMapRenderer;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.TemplateTmxMapLoader;
|
||||
import forge.adventure.world.PointOfInterest;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
/**
|
||||
* Scene that will render tiled maps.
|
||||
* Used for towns dungeons etc
|
||||
*
|
||||
*/
|
||||
public class TileMapScene extends HudScene {
|
||||
|
||||
|
||||
TiledMap map;
|
||||
PointOfInterestMapRenderer tiledMapRenderer;
|
||||
private String nextMap;
|
||||
|
||||
public TileMapScene() {
|
||||
super(MapStage.getInstance());
|
||||
tiledMapRenderer = new PointOfInterestMapRenderer((MapStage)stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (map != null)
|
||||
map.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta)
|
||||
{
|
||||
if(map==null)
|
||||
return;
|
||||
if(nextMap!=null)
|
||||
{
|
||||
load(nextMap);
|
||||
nextMap=null;
|
||||
}
|
||||
stage.act(Gdx.graphics.getDeltaTime());
|
||||
}
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
if(map==null)
|
||||
return;
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
tiledMapRenderer.setView(stage.getCamera().combined, 0, 0, Scene.GetIntendedWidth(), Scene.GetIntendedHeight());
|
||||
|
||||
tiledMapRenderer.render();
|
||||
hud.draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void load(PointOfInterest point) {
|
||||
rootPoint=point;
|
||||
oldMap=point.getData().map;
|
||||
map = new TemplateTmxMapLoader().load(Config.instance().getFilePath(point.getData().map));
|
||||
((MapStage)stage).setPointOfInterest(WorldSave.getCurrentSave().getPointOfInterestChanges(point.getID()+oldMap));
|
||||
stage.GetPlayer().setPosition(0, 0);
|
||||
WorldSave.getCurrentSave().getWorld().setSeed(point.getSeedOffset());
|
||||
tiledMapRenderer.loadMap(map,"");
|
||||
|
||||
}
|
||||
PointOfInterest rootPoint;
|
||||
String oldMap;
|
||||
|
||||
private void load(String targetMap) {
|
||||
|
||||
map = new TemplateTmxMapLoader().load(Config.instance().getFilePath(targetMap));
|
||||
((MapStage)stage).setPointOfInterest(WorldSave.getCurrentSave().getPointOfInterestChanges(rootPoint.getID()+targetMap));
|
||||
stage.GetPlayer().setPosition(0, 0);
|
||||
WorldSave.getCurrentSave().getWorld().setSeed(rootPoint.getSeedOffset());
|
||||
tiledMapRenderer.loadMap(map,oldMap);
|
||||
oldMap=targetMap;
|
||||
}
|
||||
|
||||
public void loadNext(String targetMap) {
|
||||
nextMap=targetMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.viewport.StretchViewport;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.UIActor;
|
||||
|
||||
/**
|
||||
* Base class for an GUI scene where the elements are loaded from a json file
|
||||
*/
|
||||
public class UIScene extends Scene{
|
||||
protected UIActor ui;
|
||||
Stage stage;
|
||||
|
||||
String uiFile;
|
||||
public UIScene(String uiFilePath) {
|
||||
|
||||
uiFile=uiFilePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if(stage!=null)
|
||||
stage.dispose();
|
||||
}
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
|
||||
stage.act(delta);
|
||||
}
|
||||
@Override
|
||||
public void render() {
|
||||
|
||||
Gdx.gl.glClearColor(0, 0, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.draw();
|
||||
}
|
||||
|
||||
public UIActor getUI()
|
||||
{
|
||||
return ui;
|
||||
}
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
stage = new Stage(new StretchViewport(GetIntendedWidth(), GetIntendedHeight()));
|
||||
ui = new UIActor(Config.instance().getFile(uiFile));
|
||||
screenImage=ui.findActor("lastScreen");
|
||||
stage.addActor(ui);
|
||||
|
||||
}
|
||||
Image screenImage;
|
||||
TextureRegion backgroundTexture;
|
||||
@Override
|
||||
public void enter() {
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
|
||||
|
||||
if(screenImage!=null)
|
||||
{
|
||||
if (backgroundTexture != null)
|
||||
backgroundTexture.getTexture().dispose();
|
||||
|
||||
final Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
final Pixmap potPixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Pixmap.Format.RGBA8888);
|
||||
potPixmap.setBlending(Pixmap.Blending.SourceOver);
|
||||
potPixmap.drawPixmap(pixmap, 0, 0);
|
||||
potPixmap.setColor(0,0,0,0.75f);
|
||||
potPixmap.fillRectangle(0,0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
backgroundTexture = new TextureRegion(new Texture(potPixmap), 0, Gdx.graphics.getHeight(), Gdx.graphics.getWidth(), -Gdx.graphics.getHeight());
|
||||
screenImage.setDrawable(new TextureRegionDrawable(backgroundTexture));
|
||||
}
|
||||
|
||||
super.enter();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
118
forge-adventure/src/main/java/forge/adventure/stage/GameHUD.java
Normal file
118
forge-adventure/src/main/java/forge/adventure/stage/GameHUD.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.UIActor;
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
/**
|
||||
* Stage to handle everything rendered in the HUD
|
||||
*/
|
||||
public class GameHUD extends Stage {
|
||||
|
||||
static public GameHUD instance;
|
||||
private final GameStage gameStage;
|
||||
private final Image avatar;
|
||||
private final Image miniMapPlayer;
|
||||
private final Label lifePoints;
|
||||
private final Label money;
|
||||
private Image miniMap;
|
||||
|
||||
private GameHUD(GameStage gameStage) {
|
||||
super(new FitViewport(Scene.GetIntendedWidth(), Scene.GetIntendedHeight()), gameStage.getBatch());
|
||||
instance = this;
|
||||
this.gameStage = gameStage;
|
||||
|
||||
UIActor ui = new UIActor(Config.instance().getFile("ui/hud.json"));
|
||||
miniMap = ui.findActor("map");
|
||||
|
||||
Pixmap player = new Pixmap(3, 3, Pixmap.Format.RGB888);
|
||||
player.setColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
player.fill();
|
||||
miniMapPlayer = new Image(new Texture(player));
|
||||
|
||||
|
||||
avatar = ui.findActor("avatar");
|
||||
ui.onButtonPress("menu", () -> menu());
|
||||
ui.onButtonPress("deck", () -> openDeck());
|
||||
lifePoints = ui.findActor("lifePoints");
|
||||
lifePoints.setText("20/20");
|
||||
AdventurePlayer.current().onLifeChange(()-> lifePoints.setText(AdventurePlayer.current().getLife() +"/"+ AdventurePlayer.current().getMaxLife()));
|
||||
money = ui.findActor("money");
|
||||
WorldSave.getCurrentSave().getPlayer().onGoldChange(()-> money.setText(String.valueOf(AdventurePlayer.current().getGold()))) ;
|
||||
miniMap = ui.findActor("map");
|
||||
|
||||
addActor(ui);
|
||||
addActor(miniMapPlayer);
|
||||
}
|
||||
|
||||
public static GameHUD getInstance() {
|
||||
return instance == null ? instance = new GameHUD(WorldStage.getInstance()) : instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown (int screenX, int screenY, int pointer, int button)
|
||||
{
|
||||
Vector2 c=new Vector2();
|
||||
screenToStageCoordinates(c.set(screenX, screenY));
|
||||
|
||||
float x=(c.x-miniMap.getX())/miniMap.getWidth();
|
||||
float y=(c.y-miniMap.getY())/miniMap.getHeight();
|
||||
if(x>=0&&x<=1.0&&y>=0&&y<=1.0)
|
||||
{
|
||||
WorldStage.getInstance().GetPlayer().setPosition(x*WorldSave.getCurrentSave().getWorld().getWidthInPixels(),y*WorldSave.getCurrentSave().getWorld().getHeightInPixels());
|
||||
return true;
|
||||
}
|
||||
return super.touchDown(screenX,screenY, pointer,button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
int yPos = (int) gameStage.player.getY();
|
||||
int xPos = (int) gameStage.player.getX();
|
||||
act(Gdx.graphics.getDeltaTime()); //act the Hud
|
||||
super.draw(); //draw the Hud
|
||||
int xPosMini = (int) (((float) xPos / (float) WorldSave.getCurrentSave().getWorld().getTileSize() / (float) WorldSave.getCurrentSave().getWorld().getWidthInTiles()) * miniMap.getWidth());
|
||||
int yPosMini = (int) (((float) yPos / (float) WorldSave.getCurrentSave().getWorld().getTileSize() / (float) WorldSave.getCurrentSave().getWorld().getHeightInTiles()) * miniMap.getHeight());
|
||||
miniMapPlayer.setPosition(miniMap.getX() + xPosMini - 1, miniMap.getY() + yPosMini - 1);
|
||||
}
|
||||
|
||||
Texture miniMapTexture;
|
||||
public void enter() {
|
||||
|
||||
if(miniMapTexture==null)
|
||||
{
|
||||
miniMapTexture=new Texture(WorldSave.getCurrentSave().getWorld().getBiomeImage());
|
||||
}
|
||||
|
||||
miniMap.setDrawable(new TextureRegionDrawable(miniMapTexture));
|
||||
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Object openDeck() {
|
||||
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.DeckEditScene.instance);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object menu() {
|
||||
gameStage.openMenu();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.utils.viewport.StretchViewport;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.character.MapActor;
|
||||
import forge.adventure.character.PlayerSprite;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.adventure.world.WorldSaveHeader;
|
||||
|
||||
/**
|
||||
* Base class to render a player sprite on a map
|
||||
* used for the over world and dungeons
|
||||
*/
|
||||
public abstract class GameStage extends Stage {
|
||||
|
||||
|
||||
private final OrthographicCamera camera;
|
||||
Group backgroundSprites;
|
||||
SpriteGroup foregroundSprites;
|
||||
PlayerSprite player;
|
||||
private float touchX = -1;
|
||||
private float touchY = -1;
|
||||
private final float timer = 0;
|
||||
private float animationTimeout = 0;
|
||||
|
||||
public void startPause(int i) {
|
||||
startPause(i,null);
|
||||
}
|
||||
public void startPause(int i,Runnable runnable) {
|
||||
onEndAction=runnable;
|
||||
animationTimeout=i;
|
||||
player.setMovementDirection(Vector2.Zero);
|
||||
}
|
||||
public boolean isPaused() {
|
||||
return animationTimeout>0;
|
||||
}
|
||||
|
||||
public GameStage() {
|
||||
super(new StretchViewport(Scene.GetIntendedWidth(), Scene.GetIntendedHeight(), new OrthographicCamera()));
|
||||
camera = (OrthographicCamera) getCamera();
|
||||
|
||||
backgroundSprites = new Group();
|
||||
foregroundSprites = new SpriteGroup();
|
||||
|
||||
|
||||
addActor(backgroundSprites);
|
||||
addActor(foregroundSprites);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setWinner(boolean b) {
|
||||
}
|
||||
public void setBounds(float width, float height) {
|
||||
getViewport().setWorldSize(width, height);
|
||||
}
|
||||
|
||||
public PlayerSprite GetPlayer() {
|
||||
if (player == null) {
|
||||
player = new PlayerSprite(this);
|
||||
foregroundSprites.addActor(player);
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
|
||||
public SpriteGroup GetSpriteGroup() {
|
||||
return foregroundSprites;
|
||||
}
|
||||
|
||||
public Group GetBackgroundSprites() {
|
||||
return backgroundSprites;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Runnable onEndAction;
|
||||
@Override
|
||||
public final void act(float delta) {
|
||||
super.act(delta);
|
||||
|
||||
if (animationTimeout >= 0) {
|
||||
animationTimeout -= delta;
|
||||
return;
|
||||
}
|
||||
if(isPaused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (onEndAction != null) {
|
||||
|
||||
onEndAction.run();
|
||||
onEndAction=null;
|
||||
}
|
||||
|
||||
if (touchX >= 0) {
|
||||
Vector2 target = this.screenToStageCoordinates(new Vector2(touchX, touchY));
|
||||
target.x -= player.getWidth() / 2f;
|
||||
Vector2 diff = target.sub(player.pos());
|
||||
|
||||
if (diff.len() < 2) {
|
||||
diff.setZero();
|
||||
player.stop();
|
||||
}
|
||||
player.setMovementDirection(diff);
|
||||
}
|
||||
//debug speed up
|
||||
/*
|
||||
if (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
|
||||
player.setMoveModifier(20);
|
||||
else
|
||||
player.setMoveModifier(1);*/
|
||||
|
||||
camera.position.x = Math.min(Math.max(Scene.GetIntendedWidth() / 2f, player.pos().x), getViewport().getWorldWidth() - Scene.GetIntendedWidth() / 2f);
|
||||
camera.position.y = Math.min(Math.max(Scene.GetIntendedHeight() / 2f, player.pos().y), getViewport().getWorldHeight() - Scene.GetIntendedHeight() / 2f);
|
||||
|
||||
|
||||
|
||||
onActing(delta);
|
||||
}
|
||||
|
||||
abstract protected void onActing(float delta);
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode) {
|
||||
super.keyDown(keycode);
|
||||
if (keycode == Input.Keys.LEFT || keycode == Input.Keys.A)//todo config
|
||||
{
|
||||
player.getMovementDirection().x = -1;
|
||||
}
|
||||
if (keycode == Input.Keys.RIGHT || keycode == Input.Keys.D)//todo config
|
||||
{
|
||||
player.getMovementDirection().x = +1;
|
||||
}
|
||||
if (keycode == Input.Keys.UP || keycode == Input.Keys.W)//todo config
|
||||
{
|
||||
player.getMovementDirection().y = +1;
|
||||
}
|
||||
if (keycode == Input.Keys.DOWN || keycode == Input.Keys.S)//todo config
|
||||
{
|
||||
player.getMovementDirection().y = -1;
|
||||
}
|
||||
if (keycode == Input.Keys.F12)
|
||||
{
|
||||
debugCollision(true);
|
||||
for (Actor actor : foregroundSprites.getChildren()) {
|
||||
if (actor instanceof MapActor) {
|
||||
((MapActor)actor).setBoundDebug(true);
|
||||
}
|
||||
}
|
||||
player.setBoundDebug(true);
|
||||
}
|
||||
if (keycode == Input.Keys.F11)
|
||||
{
|
||||
debugCollision(false);
|
||||
for (Actor actor : foregroundSprites.getChildren()) {
|
||||
if (actor instanceof MapActor) {
|
||||
((MapActor)actor).setBoundDebug(false);
|
||||
}
|
||||
}
|
||||
player.setBoundDebug(false);
|
||||
}
|
||||
if (keycode == Input.Keys.F10)
|
||||
{
|
||||
setDebugAll(true);
|
||||
}
|
||||
if (keycode == Input.Keys.F9)
|
||||
{
|
||||
setDebugAll(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void debugCollision(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrolled(float amountX, float amountY) {
|
||||
if(isPaused())
|
||||
return true;
|
||||
camera.zoom += (amountY * 0.03);
|
||||
if (camera.zoom < 0.2f)
|
||||
camera.zoom = 0.2f;
|
||||
if (camera.zoom > 1.5f)
|
||||
camera.zoom = 1.5f;
|
||||
return super.scrolled(amountX, amountY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDragged(int screenX, int screenY, int pointer) {
|
||||
if(isPaused())
|
||||
return true;
|
||||
touchX = screenX;
|
||||
touchY = screenY;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
|
||||
if(isPaused())
|
||||
return true;
|
||||
touchX = screenX;
|
||||
touchY = screenY;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
touchX = -1;
|
||||
touchY = -1;
|
||||
player.stop();
|
||||
}
|
||||
@Override
|
||||
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
|
||||
stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keycode) {
|
||||
if(isPaused())
|
||||
return true;
|
||||
if (keycode == Input.Keys.LEFT || keycode == Input.Keys.A || keycode == Input.Keys.RIGHT || keycode == Input.Keys.D)//todo config
|
||||
{
|
||||
player.getMovementDirection().x = 0;
|
||||
if(!player.isMoving())
|
||||
stop();
|
||||
}
|
||||
if (keycode == Input.Keys.UP || keycode == Input.Keys.W || keycode == Input.Keys.DOWN || keycode == Input.Keys.S)//todo config
|
||||
{
|
||||
player.getMovementDirection().y = 0;
|
||||
if(!player.isMoving())
|
||||
stop();
|
||||
}
|
||||
if (keycode == Input.Keys.ESCAPE) {
|
||||
openMenu();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void openMenu() {
|
||||
Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
Pixmap scaled = new Pixmap(WorldSaveHeader.previewImageWidth, (int) (WorldSaveHeader.previewImageWidth / (Scene.GetIntendedWidth() / (float) Scene.GetIntendedHeight())), Pixmap.Format.RGB888);
|
||||
scaled.drawPixmap(pixmap,
|
||||
0, 0, pixmap.getWidth(), pixmap.getHeight(),
|
||||
0, 0, scaled.getWidth(), scaled.getHeight());
|
||||
pixmap.dispose();
|
||||
if (WorldSave.getCurrentSave().header.preview != null)
|
||||
WorldSave.getCurrentSave().header.preview.dispose();
|
||||
WorldSave.getCurrentSave().header.preview = scaled;
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.StartScene.instance);
|
||||
}
|
||||
|
||||
public void enter() {
|
||||
stop();
|
||||
}
|
||||
|
||||
public void leave() {
|
||||
stop();
|
||||
}
|
||||
|
||||
public boolean isColliding(Rectangle boundingRect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public void prepareCollision(Vector2 pos, Vector2 direction, Rectangle boundingRect)
|
||||
{
|
||||
}
|
||||
|
||||
public Vector2 adjustMovement( Vector2 direction, Rectangle boundingRect)
|
||||
{
|
||||
Vector2 adjDirX=direction.cpy();
|
||||
Vector2 adjDirY=direction.cpy();
|
||||
boolean foundX=false;
|
||||
boolean foundY=false;
|
||||
while(true)
|
||||
{
|
||||
|
||||
if(!isColliding(new Rectangle(boundingRect.x+adjDirX.x,boundingRect.y+adjDirX.y, boundingRect.width, boundingRect.height)))
|
||||
{
|
||||
foundX=true;
|
||||
break;
|
||||
}
|
||||
if(adjDirX.x==0)
|
||||
break;
|
||||
|
||||
if(adjDirX.x>=0)
|
||||
adjDirX.x=Math.round(Math.max(0,adjDirX.x-1));
|
||||
else
|
||||
adjDirX.x=Math.round(Math.max(0,adjDirX.x+1));
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
if(!isColliding(new Rectangle(boundingRect.x+adjDirY.x,boundingRect.y+adjDirY.y, boundingRect.width, boundingRect.height)))
|
||||
{
|
||||
foundY=true;
|
||||
break;
|
||||
}
|
||||
if(adjDirY.y==0)
|
||||
break;
|
||||
|
||||
if(adjDirY.y>=0)
|
||||
adjDirY.y=Math.round(Math.max(0,adjDirY.y-1));
|
||||
else
|
||||
adjDirY.y=Math.round(Math.max(0,adjDirY.y+1));
|
||||
}
|
||||
if(foundY&&foundX)
|
||||
return adjDirX.len()>adjDirY.len()?adjDirX:adjDirY;
|
||||
else if(foundY)
|
||||
return adjDirY;
|
||||
else if(foundX)
|
||||
return adjDirX;
|
||||
return Vector2.Zero.cpy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import forge.adventure.data.BiomeSpriteData;
|
||||
import forge.adventure.world.PointOfInterest;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sprite actor that will render trees and rocks on the over world
|
||||
*/
|
||||
public class MapSprite extends Actor {
|
||||
|
||||
static public int BackgroundLayer = -1;
|
||||
static public int SpriteLayer = 0;
|
||||
TextureRegion texture;
|
||||
|
||||
public MapSprite(Vector2 pos, TextureRegion sprite) {
|
||||
|
||||
texture = sprite;
|
||||
setPosition(pos.x, pos.y);
|
||||
setHeight(texture.getRegionHeight());
|
||||
setWidth(texture.getRegionWidth());
|
||||
}
|
||||
|
||||
public static ArrayList<Actor> GetMapSprites(int chunkX, int chunkY) {
|
||||
ArrayList<Actor> actorGroup = new ArrayList<>();
|
||||
List<PointOfInterest> pointsOfInterest = WorldSave.getCurrentSave().getWorld().getPointsOfInterest(chunkX, chunkY);
|
||||
for (PointOfInterest poi : pointsOfInterest) {
|
||||
|
||||
Actor sprite = new PointOfInterestMapSprite(poi);
|
||||
actorGroup.add(sprite);
|
||||
}
|
||||
|
||||
|
||||
List<Pair<Vector2, Integer>> objects = WorldSave.getCurrentSave().getWorld().GetMapObjects(chunkX, chunkY);
|
||||
|
||||
for (Pair<Vector2, Integer> entry : objects) {
|
||||
BiomeSpriteData data = WorldSave.getCurrentSave().getWorld().getObject(entry.getValue());
|
||||
if (data.layer != SpriteLayer)
|
||||
continue;
|
||||
Actor sprite = new MapSprite(entry.getKey(), WorldSave.getCurrentSave().getWorld().getData().GetBiomeSprites().getSprite(data.name, (int) entry.getKey().x + (int) entry.getKey().y * 11483));
|
||||
actorGroup.add(sprite);
|
||||
}
|
||||
return actorGroup;
|
||||
}
|
||||
|
||||
public static ArrayList<Actor> GetMapSpritesBackground(int chunkX, int chunkY) {
|
||||
|
||||
List<Pair<Vector2, Integer>> objects = WorldSave.getCurrentSave().getWorld().GetMapObjects(chunkX, chunkY);
|
||||
ArrayList<Actor> actorGroup = new ArrayList<>();
|
||||
for (Pair<Vector2, Integer> entry : objects) {
|
||||
BiomeSpriteData data = WorldSave.getCurrentSave().getWorld().getObject(entry.getValue());
|
||||
if (data.layer != BackgroundLayer)
|
||||
continue;
|
||||
Actor sprite = new MapSprite(entry.getKey(), WorldSave.getCurrentSave().getWorld().getData().GetBiomeSprites().getSprite(data.name, (int) entry.getKey().x + (int) entry.getKey().y * 11483));
|
||||
actorGroup.add(sprite);
|
||||
}
|
||||
return actorGroup;
|
||||
}
|
||||
|
||||
//BitmapFont font;
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (texture == null)
|
||||
return;
|
||||
batch.draw(texture, getX(), getY());
|
||||
//font.draw(batch,String.valueOf(getZIndex()),getX()-(getWidth()/2),getY());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
|
||||
import com.badlogic.gdx.maps.MapLayer;
|
||||
import com.badlogic.gdx.maps.MapObject;
|
||||
import com.badlogic.gdx.maps.MapProperties;
|
||||
import com.badlogic.gdx.maps.objects.RectangleMapObject;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.character.*;
|
||||
import forge.adventure.data.RewardData;
|
||||
import forge.adventure.data.ShopData;
|
||||
import forge.adventure.data.WorldData;
|
||||
import forge.adventure.scene.DuelScene;
|
||||
import forge.adventure.scene.RewardScene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Reward;
|
||||
import forge.adventure.world.PointOfInterestChanges;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Stage to handle tiled maps for points of interests
|
||||
*/
|
||||
public class MapStage extends GameStage {
|
||||
|
||||
public static MapStage instance;
|
||||
Array<MapActor> actors = new Array<>();
|
||||
|
||||
TiledMap map;
|
||||
ArrayList<Rectangle>[][] collision;
|
||||
private float tileHeight;
|
||||
private float tileWidth;
|
||||
private float width;
|
||||
private float height;
|
||||
MapLayer spriteLayer;
|
||||
private PointOfInterestChanges changes;
|
||||
private EnemySprite currentMob;
|
||||
private final Vector2 oldPosition=new Vector2();//todo
|
||||
private final Vector2 oldPosition2=new Vector2();
|
||||
private final Vector2 oldPosition3=new Vector2();
|
||||
private final Vector2 oldPosition4=new Vector2();
|
||||
|
||||
public MapLayer getSpriteLayer()
|
||||
{
|
||||
return spriteLayer;
|
||||
}
|
||||
public PointOfInterestChanges getChanges()
|
||||
{
|
||||
return changes;
|
||||
}
|
||||
public static MapStage getInstance() {
|
||||
return instance == null ? instance = new MapStage() : instance;
|
||||
}
|
||||
|
||||
public void addMapActor(MapObject obj, MapActor newActor) {
|
||||
newActor.setWidth(Float.parseFloat(obj.getProperties().get("width").toString()));
|
||||
newActor.setHeight(Float.parseFloat(obj.getProperties().get("height").toString()));
|
||||
newActor.setX(Float.parseFloat(obj.getProperties().get("x").toString()));
|
||||
newActor.setY(Float.parseFloat(obj.getProperties().get("y").toString()));
|
||||
actors.add(newActor);
|
||||
foregroundSprites.addActor(newActor);
|
||||
}
|
||||
public void addMapActor(MapActor newActor) {
|
||||
actors.add(newActor);
|
||||
foregroundSprites.addActor(newActor);
|
||||
}
|
||||
@Override
|
||||
public boolean isColliding( Rectangle adjustedBoundingRect)
|
||||
{
|
||||
for(Rectangle collision:currentCollidingRectangles)
|
||||
{
|
||||
if(collision.overlaps(adjustedBoundingRect))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
final ArrayList<Rectangle> currentCollidingRectangles=new ArrayList<>();
|
||||
@Override
|
||||
public void prepareCollision(Vector2 pos, Vector2 direction, Rectangle boundingRect)
|
||||
{
|
||||
currentCollidingRectangles.clear();
|
||||
int x1= (int) (Math.min(boundingRect.x,boundingRect.x+direction.x)/tileWidth);
|
||||
int y1= (int) (Math.min(boundingRect.y,boundingRect.y+direction.y)/tileHeight);
|
||||
int x2= (int) (Math.min(boundingRect.x+boundingRect.width,boundingRect.x+boundingRect.width+direction.x)/tileWidth);
|
||||
int y2= (int) (Math.min(boundingRect.y+boundingRect.height,boundingRect.y+boundingRect.height+direction.y)/tileHeight);
|
||||
|
||||
for(int x=x1;x<=x2;x++)
|
||||
{
|
||||
for(int y=y1;y<=y2;y++)
|
||||
{
|
||||
if(x<0||x>=width||y<0||y>=height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentCollidingRectangles.addAll(collision[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Group collisionGroup;
|
||||
@Override
|
||||
protected void debugCollision(boolean b) {
|
||||
|
||||
if(collisionGroup==null)
|
||||
{
|
||||
collisionGroup=new Group();
|
||||
|
||||
for (int x = 0; x < collision.length; x++)
|
||||
{
|
||||
for (int y = 0; y < collision[x].length; y++)
|
||||
{
|
||||
for(Rectangle rectangle:collision[x][y])
|
||||
{
|
||||
MapActor collisionActor=new MapActor();
|
||||
collisionActor.setBoundDebug(true);
|
||||
collisionActor.setWidth(rectangle.width);
|
||||
collisionActor.setHeight(rectangle.height);
|
||||
collisionActor.setX(rectangle.x);
|
||||
collisionActor.setY(rectangle.y);
|
||||
collisionGroup.addActor(collisionActor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(b)
|
||||
{
|
||||
addActor(collisionGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
collisionGroup.remove();
|
||||
}
|
||||
|
||||
}
|
||||
public void loadMap(TiledMap map,String sourceMap) {
|
||||
this.map=map;
|
||||
for (MapActor actor : new Array.ArrayIterator<>(actors)) {
|
||||
actor.remove();
|
||||
foregroundSprites.removeActor(actor);
|
||||
|
||||
}
|
||||
actors = new Array<>();
|
||||
width = Float.parseFloat(map.getProperties().get("width").toString());
|
||||
height = Float.parseFloat(map.getProperties().get("height").toString());
|
||||
tileHeight = Float.parseFloat(map.getProperties().get("tileheight").toString());
|
||||
tileWidth = Float.parseFloat(map.getProperties().get("tilewidth").toString());
|
||||
setBounds(width * tileWidth, height * tileHeight);
|
||||
collision= new ArrayList[(int) width][(int) height];
|
||||
|
||||
GetPlayer().stop();
|
||||
|
||||
for(MapLayer layer: map.getLayers())
|
||||
{
|
||||
if(layer.getProperties().containsKey("spriteLayer")&&layer.getProperties().get("spriteLayer",boolean.class))
|
||||
{
|
||||
spriteLayer=layer;
|
||||
}
|
||||
if(layer instanceof TiledMapTileLayer)
|
||||
{
|
||||
loadCollision((TiledMapTileLayer)layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadObjects(layer,sourceMap);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadCollision(TiledMapTileLayer layer) {
|
||||
for(int x=0;x<layer.getWidth();x++)
|
||||
{
|
||||
for(int y=0;y<layer.getHeight();y++)
|
||||
{
|
||||
if(collision[x][y]==null)
|
||||
collision[x][y]=new ArrayList<>();
|
||||
ArrayList<Rectangle> map=collision[x][y];
|
||||
TiledMapTileLayer.Cell cell=layer.getCell(x,y);
|
||||
if(cell==null)
|
||||
continue;
|
||||
for(MapObject collision:cell.getTile().getObjects())
|
||||
{
|
||||
if(collision instanceof RectangleMapObject)
|
||||
{
|
||||
Rectangle r=((RectangleMapObject)collision).getRectangle();
|
||||
map.add(new Rectangle((Math.round(layer.getTileWidth()*x)+r.x),(Math.round(layer.getTileHeight()*y)+r.y),Math.round(r.width),Math.round(r.height)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadObjects(MapLayer layer,String sourceMap) {
|
||||
player.setMoveModifier(2);
|
||||
for (MapObject obj : layer.getObjects()) {
|
||||
|
||||
MapProperties prop=obj.getProperties();
|
||||
Object typeObject = prop.get("type");
|
||||
if (typeObject != null) {
|
||||
String type = prop.get("type",String.class);
|
||||
int id = prop.get("id",int.class);
|
||||
if(changes.isObjectDeleted(id))
|
||||
continue;
|
||||
switch (type) {
|
||||
case "entry":
|
||||
float x=Float.parseFloat(prop.get("x").toString());
|
||||
float y=Float.parseFloat(prop.get("y").toString());
|
||||
float w=Float.parseFloat(prop.get("width").toString());
|
||||
float h=Float.parseFloat(prop.get("height").toString());
|
||||
EntryActor entry=new EntryActor(this,sourceMap,id,prop.get("teleport").toString(),x,y,w,h,prop.get("direction").toString());
|
||||
addMapActor(obj, entry);
|
||||
break;
|
||||
case "enemy":
|
||||
EnemySprite mob=new EnemySprite(id, WorldData.getEnemy(prop.get("enemy").toString()));
|
||||
addMapActor(obj, mob);
|
||||
break;
|
||||
case "inn":
|
||||
addMapActor(obj, new OnCollide(() -> AdventureApplicationAdapter.instance.switchScene(SceneType.InnScene.instance)));
|
||||
break;
|
||||
case "exit":
|
||||
addMapActor(obj, new OnCollide(() -> exit()));
|
||||
break;
|
||||
case "shop":
|
||||
String shopList=prop.get("shopList").toString();
|
||||
List possibleShops=Arrays.asList(shopList.split(","));
|
||||
Array<ShopData> shops;
|
||||
if(possibleShops.size()==0||shopList.equals(""))
|
||||
shops= WorldData.getShopList();
|
||||
else
|
||||
{
|
||||
shops=new Array<>();
|
||||
for(ShopData data:new Array.ArrayIterator<>(WorldData.getShopList()))
|
||||
{
|
||||
if(possibleShops.contains(data.name))
|
||||
{
|
||||
shops.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(shops.size==0)
|
||||
continue;
|
||||
|
||||
ShopData data=shops.get(WorldSave.getCurrentSave().getWorld().getRandom().nextInt(shops.size));
|
||||
Array<Reward> ret=new Array<Reward>();
|
||||
for(RewardData rdata:new Array.ArrayIterator<>(data.rewards))
|
||||
{
|
||||
ret.addAll(rdata.generate(false));
|
||||
}
|
||||
ShopActor actor=new ShopActor(this,id,ret);
|
||||
addMapActor(obj,actor);
|
||||
if(prop.containsKey("signYOffset")&&prop.containsKey("signXOffset"))
|
||||
{
|
||||
try {
|
||||
TextureSprite sprite=new TextureSprite(Config.instance().getAtlas(data.spriteAtlas).createSprite(data.sprite));
|
||||
sprite.setX(actor.getX()+Float.parseFloat(prop.get("signXOffset").toString()));
|
||||
sprite.setY(actor.getY()+Float.parseFloat(prop.get("signYOffset").toString()));
|
||||
addMapActor(sprite);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.print("Can not create Texture for "+data.sprite+" Obj:"+data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exit() {
|
||||
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.GameScene.instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setWinner(boolean playerWins) {
|
||||
|
||||
if (playerWins) {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Death);
|
||||
startPause(1,()->getReward());
|
||||
} else {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Hit);
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
startPause(1,()->
|
||||
{
|
||||
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Idle);
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Idle);
|
||||
player.setPosition(oldPosition4);
|
||||
stop();
|
||||
currentMob=null;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void getReward()
|
||||
{
|
||||
((RewardScene)SceneType.RewardScene.instance).loadRewards(currentMob.getRewards(), RewardScene.Type.Loot, null);
|
||||
currentMob.remove();
|
||||
actors.removeValue(currentMob,true);
|
||||
changes.deleteObject(currentMob.getId());
|
||||
currentMob = null;
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.RewardScene.instance);
|
||||
}
|
||||
@Override
|
||||
protected void onActing(float delta) {
|
||||
|
||||
oldPosition4.set(oldPosition3);
|
||||
oldPosition3.set(oldPosition2);
|
||||
oldPosition2.set(oldPosition);
|
||||
oldPosition.set(player.pos());
|
||||
for (MapActor actor : new Array.ArrayIterator<>(actors)) {
|
||||
if (actor.collideWithPlayer(player)) {
|
||||
if(actor instanceof EnemySprite)
|
||||
{
|
||||
EnemySprite mob=(EnemySprite) actor;
|
||||
currentMob=mob;
|
||||
if(mob.getData().deck==null||mob.getData().deck.isEmpty())
|
||||
{
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Death);
|
||||
startPause(1,()->getReward());
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
|
||||
startPause(1,()->
|
||||
{
|
||||
((DuelScene) SceneType.DuelScene.instance).setEnemy(mob);
|
||||
((DuelScene) SceneType.DuelScene.instance).setPlayer(player);
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.DuelScene.instance);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPointOfInterest(PointOfInterestChanges change) {
|
||||
|
||||
changes =change;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.maps.MapLayer;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
|
||||
|
||||
/**
|
||||
* Custom renderer to render the game stage between the map layers of a tiled map
|
||||
*/
|
||||
public class PointOfInterestMapRenderer extends OrthogonalTiledMapRenderer {
|
||||
private final MapStage stage;
|
||||
|
||||
public PointOfInterestMapRenderer(MapStage stage) {
|
||||
super(null,stage.getBatch());
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render () {
|
||||
beginRender();
|
||||
for (MapLayer layer : map.getLayers()) {
|
||||
renderMapLayer(layer);
|
||||
if(layer==stage.getSpriteLayer())
|
||||
{
|
||||
//end render to draw character sprites
|
||||
batch.end();
|
||||
stage.draw();
|
||||
batch.begin();
|
||||
}
|
||||
}
|
||||
endRender();
|
||||
}
|
||||
|
||||
public void loadMap(TiledMap map,String sourceMap)
|
||||
{
|
||||
stage.loadMap(map,sourceMap);
|
||||
|
||||
super.setMap(map);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import forge.adventure.world.PointOfInterest;
|
||||
|
||||
/**
|
||||
* MapSprite for points of interest to add a bounding rect for collision detection
|
||||
*/
|
||||
public class PointOfInterestMapSprite extends MapSprite {
|
||||
PointOfInterest pointOfInterest;
|
||||
Texture debugTexture;
|
||||
Rectangle boundingRect;
|
||||
|
||||
public PointOfInterestMapSprite(PointOfInterest point) {
|
||||
super(point.getPosition(), point.getSprite());
|
||||
pointOfInterest = point;
|
||||
boundingRect = new Rectangle(getX(), getY(), texture.getRegionWidth(), texture.getRegionHeight());
|
||||
}
|
||||
|
||||
public PointOfInterest getPointOfInterest() {
|
||||
return pointOfInterest;
|
||||
}
|
||||
|
||||
private Texture getDebugTexture() {
|
||||
if (debugTexture == null) {
|
||||
Pixmap pixmap = new Pixmap(texture.getRegionWidth(), texture.getRegionHeight(), Pixmap.Format.RGBA8888);
|
||||
pixmap.setColor(Color.RED);
|
||||
pixmap.drawRectangle(0, 0, (int) getWidth(), (int) getHeight());
|
||||
debugTexture = new Texture(pixmap);
|
||||
pixmap.dispose();
|
||||
}
|
||||
return debugTexture;
|
||||
}
|
||||
|
||||
public Rectangle getBoundingRect() {
|
||||
return boundingRect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
super.draw(batch, parentAlpha);
|
||||
//batch.draw(getDebugTexture(),getX(),getY());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.math.Matrix4;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.utils.SnapshotArray;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Sprite group to order actors based on the Y position on the map, the render sprites further up first.
|
||||
*/
|
||||
public class SpriteGroup extends Group {
|
||||
|
||||
/**
|
||||
* Draws all children. {@link #applyTransform(Batch, Matrix4)} should be called before and {@link #resetTransform(Batch)}
|
||||
* after this method if {@link #setTransform(boolean) transform} is true. If {@link #setTransform(boolean) transform} is false
|
||||
* these methods don't need to be called, children positions are temporarily offset by the group position when drawn. This
|
||||
* method avoids drawing children completely outside the {@link #setCullingArea(Rectangle) culling area}, if set.
|
||||
*/
|
||||
@Override
|
||||
protected void drawChildren(Batch batch, float parentAlpha) {
|
||||
|
||||
Actor[] actors = getChildren().toArray();
|
||||
Arrays.sort(actors, Comparator.comparingInt(o -> (int) -o.getY()));
|
||||
|
||||
for(int i=0;i<actors.length;i++)
|
||||
{
|
||||
if(i!=actors[i].getZIndex())
|
||||
actors[i].setZIndex(i);
|
||||
}
|
||||
super.drawChildren(batch, parentAlpha);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActor(Actor actor) {
|
||||
|
||||
for (Actor child : getChildren()) {
|
||||
if (child.getY() < actor.getY()) {
|
||||
super.addActorBefore(child, actor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.addActor(actor);
|
||||
}
|
||||
|
||||
public void UpdateActorZ(Actor actor) {
|
||||
SnapshotArray<Actor> children = getChildren();
|
||||
for (int i = 0; i < children.size; i++) {
|
||||
if (children.get(i).getY() < actor.getY()) {
|
||||
actor.setZIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
actor.setZIndex(children.size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import forge.adventure.world.WorldSave;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Background for the over world, will get biome information and create chunks based on the terrain.
|
||||
*/
|
||||
public class WorldBackground extends Actor {
|
||||
|
||||
|
||||
int chunkSize;
|
||||
int tileSize;
|
||||
int playerX;
|
||||
int playerY;
|
||||
|
||||
Texture[][] chunks;
|
||||
Texture loadingTexture;
|
||||
ArrayList<Actor>[][] chunksSprites;
|
||||
ArrayList<Actor>[][] chunksSpritesBackground;
|
||||
int currentChunkX;
|
||||
int currentChunkY;
|
||||
|
||||
GameStage stage;
|
||||
|
||||
public WorldBackground(GameStage gameStage) {
|
||||
stage = gameStage;
|
||||
}
|
||||
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (chunks == null) {
|
||||
initialize();
|
||||
}
|
||||
Point pos = translateFromWorldToChunk(playerX, playerY);
|
||||
if (currentChunkX != pos.x || currentChunkY != pos.y) {
|
||||
int xDiff = currentChunkX - pos.x;
|
||||
int yDiff = currentChunkY - pos.y;
|
||||
ArrayList<Point> points = new ArrayList<Point>();
|
||||
for (int x = -1; x < 2; x++) {
|
||||
for (int y = -1; y < 2; y++) {
|
||||
points.add(new Point(pos.x + x, pos.y + y));
|
||||
}
|
||||
}
|
||||
for (int x = -1; x < 2; x++) {
|
||||
for (int y = -1; y < 2; y++) {
|
||||
Point point = new Point(currentChunkX + x, currentChunkY + y);
|
||||
if (points.contains(point))// old Point is part of new points
|
||||
{
|
||||
points.remove(point);
|
||||
} else {
|
||||
if (point.y < 0 || point.x < 0 || point.y >= chunks[0].length || point.x >= chunks.length)
|
||||
continue;
|
||||
unLoadChunk(point.x, point.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Point point : points) {
|
||||
if (point.y < 0 || point.x < 0 || point.y >= chunks[0].length || point.x >= chunks.length)
|
||||
continue;
|
||||
loadChunk(point.x, point.y);
|
||||
}
|
||||
currentChunkX = pos.x;
|
||||
currentChunkY = pos.y;
|
||||
}
|
||||
batch.disableBlending();
|
||||
for (int x = -1; x < 2; x++) {
|
||||
for (int y = -1; y < 2; y++) {
|
||||
if (pos.y + y < 0 || pos.x + x < 0 || pos.y >= chunks[0].length || pos.x >= chunks.length)
|
||||
continue;
|
||||
|
||||
|
||||
batch.draw(getChunkTexture(pos.x + x, pos.y + y), transChunkToWorld(pos.x + x), transChunkToWorld(pos.y + y));
|
||||
}
|
||||
}
|
||||
batch.enableBlending();
|
||||
|
||||
}
|
||||
|
||||
private void loadChunk(int x, int y) {
|
||||
if (chunksSprites[x][y] == null)
|
||||
chunksSprites[x][y] = MapSprite.GetMapSprites(x, y);
|
||||
|
||||
for (Actor sprite : chunksSprites[x][y]) {
|
||||
stage.GetSpriteGroup().addActor(sprite);
|
||||
}
|
||||
if (chunksSpritesBackground[x][y] == null)
|
||||
chunksSpritesBackground[x][y] = MapSprite.GetMapSpritesBackground(x, y);
|
||||
for (Actor sprite : chunksSpritesBackground[x][y]) {
|
||||
stage.GetBackgroundSprites().addActor(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
private void unLoadChunk(int x, int y) {
|
||||
ArrayList<Actor> sprites = chunksSprites[x][y];
|
||||
if (sprites != null) {
|
||||
for (Actor sprite : sprites) {
|
||||
stage.GetSpriteGroup().removeActor(sprite);
|
||||
}
|
||||
}
|
||||
sprites = chunksSpritesBackground[x][y];
|
||||
if (sprites != null) {
|
||||
for (Actor sprite : sprites) {
|
||||
stage.GetSpriteGroup().removeActor(sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Texture getChunkTexture(int x, int y) {
|
||||
Texture tex = chunks[x][y];
|
||||
if (tex == null) {
|
||||
Texture newChunk = new Texture(chunkSize * tileSize, chunkSize * tileSize, Pixmap.Format.RGB888);
|
||||
for (int cx = 0; cx < chunkSize; cx++) {
|
||||
for (int cy = 0; cy < chunkSize; cy++) {
|
||||
newChunk.draw(WorldSave.getCurrentSave().getWorld().getBiomeSprite(cx + chunkSize * x, cy + chunkSize * y), cx * tileSize, (chunkSize * tileSize) - (cy + 1) * tileSize);
|
||||
}
|
||||
}
|
||||
chunks[x][y] = newChunk;
|
||||
}
|
||||
return chunks[x][y];
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
tileSize = WorldSave.getCurrentSave().getWorld().getTileSize();
|
||||
chunkSize = WorldSave.getCurrentSave().getWorld().getChunkSize();
|
||||
chunks = new Texture[WorldSave.getCurrentSave().getWorld().getWidthInTiles()][WorldSave.getCurrentSave().getWorld().getHeightInTiles()];
|
||||
ArrayList[][] createChunks = new ArrayList[WorldSave.getCurrentSave().getWorld().getWidthInTiles()][WorldSave.getCurrentSave().getWorld().getHeightInTiles()];
|
||||
chunksSprites = createChunks;
|
||||
ArrayList[][] createSprites = new ArrayList[WorldSave.getCurrentSave().getWorld().getWidthInTiles()][WorldSave.getCurrentSave().getWorld().getHeightInTiles()];
|
||||
chunksSpritesBackground = createSprites;
|
||||
Pixmap loadPix = new Pixmap(chunkSize * tileSize, chunkSize * tileSize, Pixmap.Format.RGB565);
|
||||
loadPix.setColor(0.5f, 0.5f, 0.5f, 1);
|
||||
loadPix.fill();
|
||||
loadingTexture = new Texture(loadPix);
|
||||
}
|
||||
|
||||
int transChunkToWorld(int xy) {
|
||||
return xy * tileSize * chunkSize;
|
||||
}
|
||||
|
||||
Point translateFromWorldToChunk(float x, float y) {
|
||||
float worldWidthTiles = x / tileSize;
|
||||
float worldHeightTiles = y / tileSize;
|
||||
return new Point((int) worldWidthTiles / chunkSize, (int) worldHeightTiles / chunkSize);
|
||||
}
|
||||
|
||||
public void setPlayerPos(float x, float y) {
|
||||
|
||||
playerX = (int) x;
|
||||
playerY = (int) y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import forge.adventure.AdventureApplicationAdapter;
|
||||
import forge.adventure.character.CharacterSprite;
|
||||
import forge.adventure.character.EnemySprite;
|
||||
import forge.adventure.data.BiomeData;
|
||||
import forge.adventure.data.EnemyData;
|
||||
import forge.adventure.scene.*;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.adventure.world.World;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Stage for the over world. Will handle monster spawns
|
||||
*/
|
||||
public class WorldStage extends GameStage {
|
||||
|
||||
private static WorldStage instance=null;
|
||||
protected EnemySprite currentMob;
|
||||
protected Random rand = new Random();
|
||||
WorldBackground background;
|
||||
private float spawnDelay = 0;
|
||||
private final float spawnInterval = 4;//todo config
|
||||
private PointOfInterestMapSprite collidingPoint;
|
||||
protected ArrayList<Pair<Float, EnemySprite>> enemies = new ArrayList<>();
|
||||
private final Float dieTimer=20f;//todo config
|
||||
private Float globalTimer=0f;
|
||||
|
||||
public WorldStage() {
|
||||
super();
|
||||
background = new WorldBackground(this);
|
||||
addActor(background);
|
||||
background.setZIndex(0);
|
||||
}
|
||||
|
||||
public static WorldStage getInstance() {
|
||||
return instance == null ? instance = new WorldStage() : instance;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActing(float delta) {
|
||||
if (player.isMoving()) {
|
||||
HandleMonsterSpawn(delta);
|
||||
handlePointsOfInterestCollision();
|
||||
globalTimer+=delta;
|
||||
Iterator<Pair<Float, EnemySprite>> it = enemies.iterator();
|
||||
while (it.hasNext()) {
|
||||
Pair<Float, EnemySprite> pair= it.next();
|
||||
if(globalTimer>=pair.getKey()+dieTimer)
|
||||
{
|
||||
|
||||
foregroundSprites.removeActor(pair.getValue());
|
||||
it.remove();
|
||||
continue;
|
||||
}
|
||||
EnemySprite mob=pair.getValue();
|
||||
mob.moveTo(player,delta);
|
||||
if (player.collideWith(mob)) {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
startPause(1,()->{
|
||||
|
||||
((DuelScene) SceneType.DuelScene.instance).setEnemy(currentMob);
|
||||
((DuelScene) SceneType.DuelScene.instance).setPlayer(player);
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.DuelScene.instance);
|
||||
});
|
||||
currentMob = mob;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
for (Pair<Float, EnemySprite> pair : enemies) {
|
||||
pair.getValue().setAnimation(CharacterSprite.AnimationTypes.Idle);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void removeEnemy(EnemySprite currentMob) {
|
||||
|
||||
foregroundSprites.removeActor(currentMob);
|
||||
Iterator<Pair<Float, EnemySprite>> it = enemies.iterator();
|
||||
while (it.hasNext()) {
|
||||
Pair<Float, EnemySprite> pair = it.next();
|
||||
if (pair.getValue()==currentMob) {
|
||||
it.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setWinner(boolean playerIsWinner) {
|
||||
|
||||
if (playerIsWinner) {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Death);
|
||||
startPause(1,()->
|
||||
{
|
||||
((RewardScene)SceneType.RewardScene.instance).loadRewards(currentMob.getRewards(), RewardScene.Type.Loot, null);
|
||||
removeEnemy(currentMob);
|
||||
currentMob = null;
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.RewardScene.instance);
|
||||
} );
|
||||
} else {
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Hit);
|
||||
currentMob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
startPause(1,()->
|
||||
{
|
||||
Current.player().defeated();
|
||||
removeEnemy(currentMob);
|
||||
currentMob = null;
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private void handlePointsOfInterestCollision() {
|
||||
|
||||
for (Actor actor : foregroundSprites.getChildren()) {
|
||||
if (actor.getClass() == PointOfInterestMapSprite.class) {
|
||||
PointOfInterestMapSprite point = (PointOfInterestMapSprite) actor;
|
||||
if (player.collideWith(point.getBoundingRect())) {
|
||||
if (point == collidingPoint) {
|
||||
continue;
|
||||
}
|
||||
((TileMapScene) SceneType.TileMapScene.instance).load(point.getPointOfInterest());
|
||||
AdventureApplicationAdapter.instance.switchScene(SceneType.TileMapScene.instance);
|
||||
} else {
|
||||
if (point == collidingPoint) {
|
||||
collidingPoint = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
private void HandleMonsterSpawn(float delta) {
|
||||
|
||||
|
||||
World world = WorldSave.getCurrentSave().getWorld();
|
||||
int currentBiome = World.highestBiome(world.getBiome((int) player.getX() / world.getTileSize(), (int) player.getY() / world.getTileSize()));
|
||||
List<BiomeData> biomeData = WorldSave.getCurrentSave().getWorld().getData().GetBiomes();
|
||||
if (biomeData.size() <= currentBiome)
|
||||
{
|
||||
player.setMoveModifier(1.5f);
|
||||
return;
|
||||
}
|
||||
player.setMoveModifier(1.0f);
|
||||
BiomeData data = biomeData.get(currentBiome);
|
||||
|
||||
if (data == null)
|
||||
return;
|
||||
ArrayList<EnemyData> list = data.getEnemyList();
|
||||
if (list == null)
|
||||
return;
|
||||
spawnDelay -= delta;
|
||||
if(spawnDelay>=0)
|
||||
return;
|
||||
spawnDelay=spawnInterval+(rand.nextFloat()*4);
|
||||
EnemyData enemyData = data.getEnemy( 1);
|
||||
if (enemyData == null) {
|
||||
return;
|
||||
}
|
||||
EnemySprite sprite = new EnemySprite(enemyData);
|
||||
float unit = Scene.GetIntendedHeight() / 6f;
|
||||
Vector2 spawnPos = new Vector2(1, 1);
|
||||
spawnPos.setLength(unit + (unit * 3) * rand.nextFloat());
|
||||
spawnPos.setAngleDeg(360 * rand.nextFloat());
|
||||
sprite.setX(player.getX() + spawnPos.x);
|
||||
sprite.setY(player.getY() + spawnPos.y);
|
||||
enemies.add(Pair.of(globalTimer,sprite));
|
||||
foregroundSprites.addActor(sprite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
getBatch().begin();
|
||||
background.setPlayerPos(player.getX(), player.getY());
|
||||
getBatch().end();
|
||||
//spriteGroup.setCullingArea(new Rectangle(player.getX()-getViewport().getWorldHeight()/2,player.getY()-getViewport().getWorldHeight()/2,getViewport().getWorldHeight(),getViewport().getWorldHeight()));
|
||||
super.draw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
|
||||
GetPlayer().LoadPos();
|
||||
GetPlayer().setMovementDirection(Vector2.Zero);
|
||||
for (Actor actor : foregroundSprites.getChildren()) {
|
||||
if (actor.getClass() == PointOfInterestMapSprite.class) {
|
||||
PointOfInterestMapSprite point = (PointOfInterestMapSprite) actor;
|
||||
if (player.collideWith(point.getBoundingRect())) {
|
||||
collidingPoint = point;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setBounds(WorldSave.getCurrentSave().getWorld().getWidthInPixels(), WorldSave.getCurrentSave().getWorld().getHeightInPixels());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave() {
|
||||
GetPlayer().storePos();
|
||||
}
|
||||
}
|
||||
500
forge-adventure/src/main/java/forge/adventure/util/CardUtil.java
Normal file
500
forge-adventure/src/main/java/forge/adventure/util/CardUtil.java
Normal file
@@ -0,0 +1,500 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import forge.adventure.data.GeneratedDeckData;
|
||||
import forge.adventure.data.GeneratedDeckTemplateData;
|
||||
import forge.adventure.data.RewardData;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.deck.io.DeckSerializer;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility class to deck generation and card filtering
|
||||
*/
|
||||
public class CardUtil {
|
||||
public static final class CardPredicate implements Predicate<PaperCard> {
|
||||
enum ColorType
|
||||
{
|
||||
Any,
|
||||
Colorless,
|
||||
MultiColor,
|
||||
MonoColor
|
||||
}
|
||||
private final List<CardRarity> rarities=new ArrayList<>();
|
||||
private final List<String> editions=new ArrayList<>();
|
||||
private final List<String> subType=new ArrayList<>();
|
||||
private final List<String> keyWords=new ArrayList<>();
|
||||
private final List<CardType.CoreType> type=new ArrayList<>();
|
||||
private final List<CardType.Supertype> superType=new ArrayList<>();
|
||||
private final List<Integer> manaCosts =new ArrayList<>();
|
||||
private final Pattern text;
|
||||
private final boolean matchAllSubTypes;
|
||||
private int colors;
|
||||
private final ColorType colorType;
|
||||
private final boolean shouldBeEqual;
|
||||
|
||||
@Override
|
||||
public boolean apply(final PaperCard card) {
|
||||
if(!this.rarities.isEmpty()&&!this.rarities.contains(card.getRarity()))
|
||||
return !this.shouldBeEqual;
|
||||
if(!this.editions.isEmpty()&&!this.editions.contains(card.getEdition()))
|
||||
return !this.shouldBeEqual;
|
||||
if(!this.manaCosts.isEmpty()&&!this.manaCosts.contains(card.getRules().getManaCost().getCMC()))
|
||||
return !this.shouldBeEqual;
|
||||
if(this.text!=null&& !this.text.matcher(card.getRules().getOracleText()).find())
|
||||
return !this.shouldBeEqual;
|
||||
|
||||
if(this.colors!= MagicColor.ALL_COLORS)
|
||||
{
|
||||
if(!card.getRules().getColor().hasNoColorsExcept(this.colors)||card.getRules().getColor().isColorless())
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
if(colorType!=ColorType.Any)
|
||||
{
|
||||
switch (colorType)
|
||||
{
|
||||
case Colorless:
|
||||
if(!card.getRules().getColor().isColorless())
|
||||
return !this.shouldBeEqual;
|
||||
break;
|
||||
case MonoColor:
|
||||
if(!card.getRules().getColor().isMonoColor())
|
||||
return !this.shouldBeEqual;
|
||||
break;
|
||||
case MultiColor:
|
||||
if(!card.getRules().getColor().isMulticolor())
|
||||
return !this.shouldBeEqual;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!this.type.isEmpty())
|
||||
{
|
||||
boolean found=false;
|
||||
for(CardType.CoreType type:card.getRules().getType().getCoreTypes())
|
||||
{
|
||||
if(this.type.contains(type))
|
||||
{
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
if(!this.superType.isEmpty())
|
||||
{
|
||||
boolean found=false;
|
||||
for(CardType.Supertype type:card.getRules().getType().getSupertypes())
|
||||
{
|
||||
if(this.superType.contains(type))
|
||||
{
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
if(this.matchAllSubTypes)
|
||||
{
|
||||
if(!this.subType.isEmpty())
|
||||
{
|
||||
if(this.subType.size()!= Iterables.size(card.getRules().getType().getSubtypes()))
|
||||
return !this.shouldBeEqual;
|
||||
for(String subtype:card.getRules().getType().getSubtypes())
|
||||
{
|
||||
if(!this.subType.contains(subtype))
|
||||
{
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!this.subType.isEmpty())
|
||||
{
|
||||
boolean found=false;
|
||||
for(String subtype:card.getRules().getType().getSubtypes())
|
||||
{
|
||||
if(this.subType.contains(subtype))
|
||||
{
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.keyWords.isEmpty())
|
||||
{
|
||||
boolean found=false;
|
||||
for(String keyWord:this.keyWords)
|
||||
{
|
||||
if(card.getRules().hasKeyword(keyWord))
|
||||
{
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
return !this.shouldBeEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return this.shouldBeEqual;
|
||||
}
|
||||
|
||||
public CardPredicate(final RewardData type, final boolean wantEqual) {
|
||||
this.matchAllSubTypes=type.matchAllSubTypes;
|
||||
this.shouldBeEqual = wantEqual;
|
||||
for(int i=0;type.manaCosts!=null&&i<type.manaCosts.length;i++)
|
||||
manaCosts.add(type.manaCosts[i]);
|
||||
text = type.cardText==null||type.cardText.isEmpty()?null:Pattern.compile(type.cardText, Pattern.CASE_INSENSITIVE);
|
||||
if(type.colors==null||type.colors.length==0)
|
||||
{
|
||||
this.colors=MagicColor.ALL_COLORS;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.colors=0;
|
||||
for(String color:type.colors)
|
||||
{
|
||||
colors|=MagicColor.fromName(color.toLowerCase());
|
||||
}
|
||||
}
|
||||
if(type.keyWords!=null&&type.keyWords.length!=0)
|
||||
{
|
||||
keyWords.addAll(Arrays.asList(type.keyWords));
|
||||
}
|
||||
if(type.rarity!=null&&type.rarity.length!=0)
|
||||
{
|
||||
for(String rarity:type.rarity)
|
||||
{
|
||||
rarities.add(CardRarity.smartValueOf(rarity));
|
||||
}
|
||||
}
|
||||
|
||||
if(type.subTypes!=null&&type.subTypes.length!=0)
|
||||
{
|
||||
subType.addAll(Arrays.asList(type.subTypes));
|
||||
}
|
||||
if(type.editions!=null&&type.editions.length!=0)
|
||||
{
|
||||
editions.addAll(Arrays.asList(type.editions));
|
||||
}
|
||||
if(type.superTypes!=null&&type.superTypes.length!=0)
|
||||
{
|
||||
for(String string:type.superTypes)
|
||||
superType.add(CardType.Supertype.getEnum(string));
|
||||
}
|
||||
if(type.cardTypes!=null&&type.cardTypes.length!=0)
|
||||
{
|
||||
for(String string:type.cardTypes)
|
||||
this.type.add(CardType.CoreType.getEnum(string));
|
||||
}
|
||||
if(type.colorType!=null&&!type.colorType.isEmpty())
|
||||
{
|
||||
this.colorType=ColorType.valueOf(type.colorType);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.colorType=ColorType.Any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PaperCard> generateCards(Iterable<PaperCard> cards,final RewardData data, final int count)
|
||||
{
|
||||
|
||||
final List<PaperCard> result = new ArrayList<>();
|
||||
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
CardPredicate pre=new CardPredicate(data, true);
|
||||
PaperCard card = null;
|
||||
int lowest = Integer.MAX_VALUE;
|
||||
for (final PaperCard item : cards)
|
||||
{
|
||||
if(!pre.apply(item))
|
||||
continue;
|
||||
int next = WorldSave.getCurrentSave().getWorld().getRandom().nextInt();
|
||||
if(next < lowest) {
|
||||
lowest = next;
|
||||
card = item;
|
||||
}
|
||||
}
|
||||
if (card != null )
|
||||
result.add(card);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public static int getCardPrice(PaperCard card)
|
||||
{
|
||||
switch (card.getRarity())
|
||||
{
|
||||
case BasicLand:
|
||||
return 20;
|
||||
case Common:
|
||||
return 50;
|
||||
case Uncommon:
|
||||
return 150;
|
||||
case Rare:
|
||||
return 300;
|
||||
case MythicRare:
|
||||
return 500;
|
||||
default:
|
||||
return 90000;
|
||||
}
|
||||
}
|
||||
|
||||
public static Deck generateDeck(GeneratedDeckData data)
|
||||
{
|
||||
Deck deck= new Deck(data.name);
|
||||
if(data.template==null)
|
||||
{
|
||||
deck.getOrCreate(DeckSection.Main).addAllFlat(RewardData.generateAllCards(Arrays.asList(data.mainDeck), true));
|
||||
if(data.sideBoard!=null)
|
||||
deck.getOrCreate(DeckSection.Sideboard).addAllFlat(RewardData.generateAllCards(Arrays.asList(data.sideBoard), true));
|
||||
return deck;
|
||||
}
|
||||
float count=data.template.count;
|
||||
float lands=count*0.4f;
|
||||
float spells=count-lands;
|
||||
List<RewardData> dataArray= generateRewards(data.template,spells*0.5f,new int[]{1,2});
|
||||
dataArray.addAll(generateRewards(data.template,spells*0.3f,new int[]{3,4,5}));
|
||||
dataArray.addAll(generateRewards(data.template,spells*0.2f,new int[]{6,7,8}));
|
||||
List<PaperCard> nonLand=RewardData.generateAllCards(dataArray, true);
|
||||
|
||||
nonLand.addAll(fillWithLands(nonLand,data.template));
|
||||
deck.getOrCreate(DeckSection.Main).addAllFlat(nonLand);
|
||||
return deck;
|
||||
}
|
||||
|
||||
private static List<PaperCard> fillWithLands(List<PaperCard> nonLands, GeneratedDeckTemplateData template) {
|
||||
int red=0;
|
||||
int blue=0;
|
||||
int green=0;
|
||||
int white=0;
|
||||
int black=0;
|
||||
int colorLess=0;
|
||||
int cardCount=nonLands.size();
|
||||
List<PaperCard> cards=new ArrayList<>();
|
||||
for(PaperCard nonLand:nonLands)
|
||||
{
|
||||
red+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.RED);
|
||||
green+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.GREEN);
|
||||
white+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.WHITE);
|
||||
blue+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.BLUE);
|
||||
black+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.BLACK);
|
||||
colorLess+=nonLand.getRules().getManaCost().getShardCount(ManaCostShard.GENERIC);
|
||||
}
|
||||
float sum= red+ blue+ green+ white+ black;
|
||||
int neededLands=template.count-cardCount;
|
||||
int neededDualLands= Math.round (neededLands*template.rares);
|
||||
int neededBase=neededLands-neededDualLands;
|
||||
if(sum==0.)
|
||||
{
|
||||
cards.addAll(generateLands("Wastes",neededLands));
|
||||
}
|
||||
else
|
||||
{
|
||||
int mount=Math.round(neededBase*(red/sum));
|
||||
int island=Math.round(neededBase*(blue/sum));
|
||||
int forest=Math.round(neededBase*(green/sum));
|
||||
int plains=Math.round(neededBase*(white/sum));
|
||||
int swamp=Math.round(neededBase*(black/sum));
|
||||
cards.addAll(generateLands("Plains",plains));
|
||||
cards.addAll(generateLands("Island",island));
|
||||
cards.addAll(generateLands("Forest",forest));
|
||||
cards.addAll(generateLands("Mountain",mount));
|
||||
cards.addAll(generateLands("Swamp",swamp));
|
||||
List<String> landTypes=new ArrayList<>();
|
||||
if(mount>0)
|
||||
landTypes.add("Mountain");
|
||||
if(island>0)
|
||||
landTypes.add("Island");
|
||||
if(plains>0)
|
||||
landTypes.add("Plains");
|
||||
if(swamp>0)
|
||||
landTypes.add("Swamp");
|
||||
if(forest>0)
|
||||
landTypes.add("Forest");
|
||||
cards.addAll(generateDualLands(landTypes,neededDualLands));
|
||||
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
|
||||
private static Collection<PaperCard> generateDualLands(List<String> landName, int count) {
|
||||
ArrayList<RewardData> rewards=new ArrayList<>();
|
||||
RewardData base= new RewardData();
|
||||
rewards.add(base);
|
||||
base.cardTypes=new String[]{"Land"};
|
||||
base.count=count;
|
||||
base.matchAllSubTypes=true;
|
||||
if(landName.size()==1)
|
||||
{
|
||||
base.subTypes=new String[]{landName.get(0)};
|
||||
}
|
||||
else if(landName.size()==2)
|
||||
{
|
||||
base.subTypes=new String[]{landName.get(0),landName.get(1)};
|
||||
}
|
||||
else if(landName.size()==3)
|
||||
{
|
||||
RewardData sub1= new RewardData(base);
|
||||
RewardData sub2= new RewardData(base);
|
||||
sub1.count/=3;
|
||||
sub2.count/=3;
|
||||
base.count-=sub1.count;
|
||||
base.count-=sub2.count;
|
||||
|
||||
base.subTypes=new String[]{landName.get(0),landName.get(1)};
|
||||
sub1.subTypes=new String[]{landName.get(1),landName.get(2)};
|
||||
sub2.subTypes=new String[]{landName.get(0),landName.get(2)};
|
||||
rewards.addAll(Arrays.asList(sub1,sub2));
|
||||
}
|
||||
else if(landName.size()==4)
|
||||
{
|
||||
RewardData sub1= new RewardData(base);
|
||||
RewardData sub2= new RewardData(base);
|
||||
RewardData sub3= new RewardData(base);
|
||||
RewardData sub4= new RewardData(base);
|
||||
sub1.count/=5;
|
||||
sub2.count/=5;
|
||||
sub3.count/=5;
|
||||
sub4.count/=5;
|
||||
base.count-=sub1.count;
|
||||
base.count-=sub2.count;
|
||||
base.count-=sub3.count;
|
||||
base.count-=sub4.count;
|
||||
|
||||
base.subTypes = new String[]{landName.get(0),landName.get(1)};
|
||||
sub1.subTypes = new String[]{landName.get(0),landName.get(2)};
|
||||
sub2.subTypes = new String[]{landName.get(0),landName.get(3)};
|
||||
sub3.subTypes = new String[]{landName.get(1),landName.get(2)};
|
||||
sub4.subTypes = new String[]{landName.get(1),landName.get(3)};
|
||||
rewards.addAll(Arrays.asList(sub1,sub2,sub3,sub4));
|
||||
}
|
||||
else if(landName.size()==5)
|
||||
{
|
||||
RewardData sub1= new RewardData(base);
|
||||
RewardData sub2= new RewardData(base);
|
||||
RewardData sub3= new RewardData(base);
|
||||
RewardData sub4= new RewardData(base);
|
||||
RewardData sub5= new RewardData(base);
|
||||
RewardData sub6= new RewardData(base);
|
||||
RewardData sub7= new RewardData(base);
|
||||
RewardData sub8= new RewardData(base);
|
||||
RewardData sub9= new RewardData(base);
|
||||
sub1.count/=10;
|
||||
sub2.count/=10;
|
||||
sub3.count/=10;
|
||||
sub4.count/=10;
|
||||
sub5.count/=10;
|
||||
sub6.count/=10;
|
||||
sub7.count/=10;
|
||||
sub8.count/=10;
|
||||
sub9.count/=10;
|
||||
base.count-=sub1.count;
|
||||
base.count-=sub2.count;
|
||||
base.count-=sub3.count;
|
||||
base.count-=sub4.count;
|
||||
base.count-=sub5.count;
|
||||
base.count-=sub6.count;
|
||||
base.count-=sub7.count;
|
||||
base.count-=sub8.count;
|
||||
base.count-=sub9.count;
|
||||
|
||||
base.subTypes=new String[]{landName.get(0),landName.get(1)};
|
||||
sub1.subTypes=new String[]{landName.get(0),landName.get(2)};
|
||||
sub2.subTypes=new String[]{landName.get(0),landName.get(3)};
|
||||
sub3.subTypes=new String[]{landName.get(0),landName.get(4)};
|
||||
sub4.subTypes=new String[]{landName.get(1),landName.get(2)};
|
||||
sub5.subTypes=new String[]{landName.get(1),landName.get(3)};
|
||||
sub6.subTypes=new String[]{landName.get(1),landName.get(4)};
|
||||
sub7.subTypes=new String[]{landName.get(2),landName.get(3)};
|
||||
sub8.subTypes=new String[]{landName.get(2),landName.get(4)};
|
||||
sub9.subTypes=new String[]{landName.get(3),landName.get(4)};
|
||||
rewards.addAll(Arrays.asList(sub1,sub2,sub3,sub4,sub5,sub6,sub7,sub8,sub9));
|
||||
}
|
||||
|
||||
Collection<PaperCard> ret = new ArrayList<>(RewardData.generateAllCards(rewards, true));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static Collection<PaperCard> generateLands(String landName,int count) {
|
||||
Collection<PaperCard> ret=new ArrayList<>();
|
||||
for(int i=0;i<count;i++)
|
||||
ret.add(FModel.getMagicDb().getCommonCards().getCard(landName));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static List<RewardData> generateRewards(GeneratedDeckTemplateData template, float count, int[] manaCosts) {
|
||||
ArrayList<RewardData> ret=new ArrayList<>();
|
||||
ret.addAll(templateGenerate(template,count-(count*template.rares),manaCosts,new String[]{"Uncommon","Common"}));
|
||||
ret.addAll(templateGenerate(template,count*template.rares,manaCosts,new String[]{"Rare","Mythic Rare"}));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static ArrayList<RewardData> templateGenerate(GeneratedDeckTemplateData template, float count, int[] manaCosts, String[] strings) {
|
||||
ArrayList<RewardData> ret=new ArrayList<>();
|
||||
RewardData base= new RewardData();
|
||||
base.manaCosts=manaCosts;
|
||||
base.rarity=strings;
|
||||
base.colors=template.colors;
|
||||
if(template.tribe!=null&&!template.tribe.isEmpty())
|
||||
{
|
||||
RewardData caresAbout= new RewardData(base);
|
||||
caresAbout.cardText="\\b"+template.tribe+"\\b";
|
||||
caresAbout.count= Math.round(count*template.tribeSynergyCards);
|
||||
ret.add(caresAbout);
|
||||
|
||||
base.subTypes=new String[]{template.tribe};
|
||||
base.count= Math.round(count*(1-template.tribeSynergyCards));
|
||||
}
|
||||
else
|
||||
{
|
||||
base.count= Math.round(count);
|
||||
}
|
||||
ret.add(base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Deck getDeck(String path)
|
||||
{
|
||||
if(path.endsWith(".dck"))
|
||||
return DeckSerializer.fromFile(new File(Config.instance().getFilePath(path)));
|
||||
|
||||
Json json = new Json();
|
||||
FileHandle handle = Config.instance().getFile(path);
|
||||
if (handle.exists())
|
||||
return generateDeck(json.fromJson(GeneratedDeckData.class, handle));
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
139
forge-adventure/src/main/java/forge/adventure/util/Config.java
Normal file
139
forge-adventure/src/main/java/forge/adventure/util/Config.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonWriter;
|
||||
import forge.adventure.data.ConfigData;
|
||||
import forge.adventure.data.SettingData;
|
||||
import forge.deck.Deck;
|
||||
import forge.localinstance.properties.ForgeConstants;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.localinstance.properties.ForgeProfileProperties;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Main resource class to access files from the selected adventure
|
||||
*/
|
||||
public class Config {
|
||||
private static Config currentConfig;
|
||||
private final String prefix;
|
||||
private final HashMap<String, FileHandle> Cache = new HashMap<String, FileHandle>();
|
||||
private final HashMap<String, TextureAtlas> atlasCache = new HashMap<>();
|
||||
private final ConfigData configData;
|
||||
private final String[] adventures;
|
||||
private SettingData settingsData;
|
||||
private String Lang = "en-us";
|
||||
private final String plane;
|
||||
|
||||
static public Config instance()
|
||||
{
|
||||
if(currentConfig==null)
|
||||
currentConfig=new Config();
|
||||
return currentConfig;
|
||||
}
|
||||
private Config() {
|
||||
|
||||
String path= Files.exists(Paths.get("./res"))?"./":"../forge-gui/";
|
||||
adventures = new File(path + "/res/adventure").list();
|
||||
try
|
||||
{
|
||||
settingsData = new Json().fromJson(SettingData.class, new FileHandle(ForgeConstants.USER_DIR + "/adventure/settings.json"));
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
settingsData=new SettingData();
|
||||
}
|
||||
if(settingsData.plane==null||settingsData.plane.isEmpty())
|
||||
{
|
||||
if(adventures!=null&&adventures.length>=1)
|
||||
settingsData.plane=adventures[0];
|
||||
}
|
||||
|
||||
if(settingsData.width==0||settingsData.height==0)
|
||||
{
|
||||
settingsData.width=1280;
|
||||
settingsData.height=720;
|
||||
}
|
||||
|
||||
this.plane = settingsData.plane;
|
||||
currentConfig = this;
|
||||
|
||||
prefix = path + "/res/adventure/" + plane + "/";
|
||||
if (FModel.getPreferences() != null)
|
||||
Lang = FModel.getPreferences().getPref(ForgePreferences.FPref.UI_LANGUAGE);
|
||||
configData = new Json().fromJson(ConfigData.class, new FileHandle(prefix + "config.json"));
|
||||
|
||||
}
|
||||
|
||||
public ConfigData getConfigData() {
|
||||
return configData;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getFilePath(String path) {
|
||||
return prefix + path;
|
||||
}
|
||||
|
||||
public FileHandle getFile(String path) {
|
||||
String fullPath = prefix + path;
|
||||
if (!Cache.containsKey(fullPath)) {
|
||||
|
||||
String fileName = fullPath.replaceFirst("[.][^.]+$", "");
|
||||
String ext = fullPath.substring(fullPath.lastIndexOf('.'));
|
||||
String langFile = fileName + "-" + Lang + ext;
|
||||
if (Files.exists(Paths.get(langFile))) {
|
||||
Cache.put(fullPath, new FileHandle(langFile));
|
||||
} else {
|
||||
Cache.put(fullPath, new FileHandle(fullPath));
|
||||
}
|
||||
}
|
||||
return Cache.get(fullPath);
|
||||
}
|
||||
|
||||
|
||||
public String getPlane() {
|
||||
return plane;
|
||||
}
|
||||
|
||||
public Deck[] starterDecks() {
|
||||
|
||||
Deck[] deck = new Deck[configData.starterDecks.length];
|
||||
for (int i = 0; i < configData.starterDecks.length; i++) {
|
||||
deck[i] = CardUtil.getDeck(configData.starterDecks[i]);
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
public TextureAtlas getAtlas(String spriteAtlas) {
|
||||
if (!atlasCache.containsKey(spriteAtlas)) {
|
||||
atlasCache.put(spriteAtlas, new TextureAtlas(getFile(spriteAtlas)));
|
||||
}
|
||||
return atlasCache.get(spriteAtlas);
|
||||
}
|
||||
public SettingData getSettingData()
|
||||
{
|
||||
return settingsData;
|
||||
}
|
||||
public String[] getAllAdventures()
|
||||
{
|
||||
return adventures;
|
||||
}
|
||||
|
||||
public void saveSettings() {
|
||||
|
||||
Json json = new Json(JsonWriter.OutputType.json);
|
||||
FileHandle handle = new FileHandle(ForgeProfileProperties.getUserDir() + "/adventure/settings.json");
|
||||
handle.writeString(json.prettyPrint(json.toJson(settingsData, SettingData.class)),false);
|
||||
|
||||
}
|
||||
}
|
||||
129
forge-adventure/src/main/java/forge/adventure/util/Controls.java
Normal file
129
forge-adventure/src/main/java/forge/adventure/util/Controls.java
Normal file
@@ -0,0 +1,129 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
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.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Class to create ui elements in the correct style
|
||||
*/
|
||||
public class Controls {
|
||||
private static Skin SelectedSkin = null;
|
||||
|
||||
static public TextButton newTextButton(String text) {
|
||||
|
||||
return new TextButton(text, GetSkin());
|
||||
}
|
||||
|
||||
static public SelectBox newComboBox(String[] text, String item, Function<Object, Void> func) {
|
||||
|
||||
SelectBox ret = new SelectBox<String>(GetSkin());
|
||||
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.setSelected(item);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static public TextField newTextField(String text) {
|
||||
return new TextField(text, GetSkin());
|
||||
}
|
||||
|
||||
static public TextField newTextField(String text, Function<String, Void> func) {
|
||||
TextField ret = new TextField(text, GetSkin());
|
||||
ret.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
try {
|
||||
func.apply(((TextField) actor).getText());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public TextButton newTextButton(String text, Runnable func) {
|
||||
TextButton ret = newTextButton(text);
|
||||
ret.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
try {
|
||||
func.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public Slider newSlider(float min, float max, float step, boolean vertical) {
|
||||
Slider ret = new Slider(min, max, step, vertical, GetSkin());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public CheckBox newCheckBox(String text) {
|
||||
CheckBox ret = new CheckBox(text, GetSkin());
|
||||
return ret;
|
||||
}
|
||||
static public BitmapFont bigFont()
|
||||
{
|
||||
return SelectedSkin.getFont("big");
|
||||
}
|
||||
static public BitmapFont font()
|
||||
{
|
||||
return SelectedSkin.getFont("default");
|
||||
}
|
||||
|
||||
|
||||
static public Skin GetSkin() {
|
||||
|
||||
if (SelectedSkin == null) {
|
||||
SelectedSkin = new Skin();
|
||||
|
||||
|
||||
|
||||
FileHandle skinFile = Config.instance().getFile(Paths.SKIN);
|
||||
FileHandle atlasFile = skinFile.sibling(skinFile.nameWithoutExtension() + ".atlas");
|
||||
TextureAtlas atlas = new TextureAtlas(atlasFile);
|
||||
SelectedSkin.addRegions(atlas);
|
||||
|
||||
SelectedSkin.load(skinFile);
|
||||
}
|
||||
return SelectedSkin;
|
||||
}
|
||||
|
||||
public static Label newLabel(String name) {
|
||||
|
||||
Label ret = new Label(name, GetSkin());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Dialog newDialog(String title) {
|
||||
Dialog ret = new Dialog(title, GetSkin());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import forge.adventure.world.AdventurePlayer;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.deck.Deck;
|
||||
/**
|
||||
* Shortcut class to handle global access, may need some redesign
|
||||
*/
|
||||
public class Current {
|
||||
public static AdventurePlayer player()
|
||||
{
|
||||
return WorldSave.getCurrentSave().getPlayer();
|
||||
}
|
||||
|
||||
static Deck deck;
|
||||
public static Deck latestDeck() {
|
||||
return deck;
|
||||
}
|
||||
public static void setLatestDeck(Deck generateDeck) {
|
||||
deck=generateDeck;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.TextureData;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
|
||||
/*
|
||||
Class to draw directly on a pixmap
|
||||
*/
|
||||
public abstract class DrawOnPixmap {
|
||||
public static void draw(Pixmap on, TextureRegion from)
|
||||
{
|
||||
draw(on,0,0,from);
|
||||
|
||||
}
|
||||
public static void draw(Pixmap on,int x,int y, TextureRegion from)
|
||||
{
|
||||
TextureData textureData = from.getTexture().getTextureData();
|
||||
if (!textureData.isPrepared()) {
|
||||
textureData.prepare();
|
||||
}
|
||||
on.drawPixmap( textureData.consumePixmap(), x, y, from.getRegionX(), from.getRegionY(), from.getRegionWidth(), from.getRegionHeight() );
|
||||
|
||||
}
|
||||
|
||||
public static void drawText(Pixmap drawingMap, String text, int x, int y, float width) {
|
||||
|
||||
BitmapFont font=Controls.bigFont();
|
||||
|
||||
BitmapFont.BitmapFontData data=font.getData();
|
||||
Pixmap source=new Pixmap(Gdx.files.internal(data.imagePaths[0]));
|
||||
|
||||
float totalLength=data.getGlyph('0').width*text.length();
|
||||
float xOffset=(width-totalLength)/2;
|
||||
xOffset+=x;
|
||||
for(char c:text.toCharArray())
|
||||
{
|
||||
|
||||
drawingMap.drawPixmap(source, (int)xOffset, y,
|
||||
data.getGlyph(c).srcX, data.getGlyph(c).srcY, data.getGlyph(c).width, data.getGlyph(c).height);
|
||||
xOffset+=data.getGlyph(c).width+1;
|
||||
}
|
||||
source.dispose();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
/**
|
||||
* Defines for the hard coded paths
|
||||
*/
|
||||
public class Paths {
|
||||
public static final String ENEMIES = "world/enemies.json";
|
||||
public static final String SHOPS = "world/shops.json";
|
||||
public static final String WORLD = "world/world.json";
|
||||
public static final String HEROES = "world/heroes.json";
|
||||
public static final String POINTS_OF_INTEREST = "world/points_of_interest.json";
|
||||
public static final String SKIN = "skin/ui_skin.json";
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import forge.item.PaperCard;
|
||||
|
||||
/**
|
||||
* Reward class that may contain gold,cards or items
|
||||
*/
|
||||
public class Reward {
|
||||
|
||||
|
||||
|
||||
public PaperCard getCard() {
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
public enum Type {
|
||||
Card,
|
||||
Gold,
|
||||
Item,
|
||||
Life
|
||||
|
||||
}
|
||||
Type type;
|
||||
PaperCard card;
|
||||
|
||||
private final int count;
|
||||
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
public Reward(int count) {
|
||||
type=Type.Gold;
|
||||
this.count =count;
|
||||
}
|
||||
public Reward(PaperCard card)
|
||||
{
|
||||
type= Type.Card;
|
||||
this.card=card;
|
||||
count = 0;
|
||||
}
|
||||
public Reward(Type type, int count) {
|
||||
this.type=type;
|
||||
this.count =count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
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.MathUtils;
|
||||
import com.badlogic.gdx.math.Matrix4;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Tooltip;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import forge.adventure.scene.RewardScene;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.ImageCache;
|
||||
import forge.gui.GuiBase;
|
||||
import forge.util.ImageFetcher;
|
||||
|
||||
/**
|
||||
* Render the rewards as a card on the reward scene.
|
||||
*
|
||||
*/
|
||||
public class RewardActor extends Actor implements Disposable, ImageFetcher.Callback {
|
||||
Tooltip<Image> tooltip;
|
||||
Reward reward;
|
||||
|
||||
static TextureRegion backTexture;
|
||||
Texture image;
|
||||
boolean needsToBeDisposed;
|
||||
float flipProcess=0;
|
||||
boolean clicked=false;
|
||||
boolean flipOnClick;
|
||||
private boolean hover;
|
||||
|
||||
static final ImageFetcher fetcher = GuiBase.getInterface().getImageFetcher();
|
||||
Image toolTipImage;
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
if(needsToBeDisposed)
|
||||
image.dispose();
|
||||
}
|
||||
|
||||
public Reward getReward() {
|
||||
return reward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImageFetched() {
|
||||
if(ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false)))
|
||||
{
|
||||
setCardImage(ImageCache.getImage(reward.getCard().getImageKey(false),false));
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type
|
||||
{
|
||||
Shop,
|
||||
Loot
|
||||
|
||||
}
|
||||
public RewardActor(Reward reward,boolean flippable)
|
||||
{
|
||||
|
||||
this.flipOnClick=flippable;
|
||||
this.reward=reward;
|
||||
if(backTexture==null)
|
||||
{
|
||||
backTexture= FSkin.getSleeves().get(0);
|
||||
}
|
||||
switch (reward.type)
|
||||
{
|
||||
case Card:
|
||||
if(ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false)))
|
||||
{
|
||||
setCardImage( ImageCache.getImage(reward.getCard().getImageKey(false),false));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false))) {
|
||||
fetcher.fetchImage(reward.getCard().getImageKey(false), this);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Gold:
|
||||
{
|
||||
|
||||
TextureAtlas atlas= Config.instance().getAtlas("sprites/items.atlas");
|
||||
Sprite backSprite=atlas.createSprite("CardBack");
|
||||
Pixmap drawingMap=new Pixmap((int)backSprite.getWidth(),(int)backSprite.getHeight(), Pixmap.Format.RGBA8888);
|
||||
|
||||
DrawOnPixmap.draw(drawingMap,backSprite);
|
||||
Sprite gold=atlas.createSprite("Gold");
|
||||
DrawOnPixmap.draw(drawingMap,(int)((backSprite.getWidth()/2f)-gold.getWidth()/2f),(int)((backSprite.getHeight()/4f)*1f),gold);
|
||||
DrawOnPixmap.drawText(drawingMap,String.valueOf(reward.getCount()),0,(int)((backSprite.getHeight()/4f)*2f),backSprite.getWidth());
|
||||
|
||||
image=new Texture(drawingMap);
|
||||
drawingMap.dispose();
|
||||
needsToBeDisposed=true;
|
||||
break;
|
||||
}
|
||||
case Life:
|
||||
{
|
||||
TextureAtlas atlas = Config.instance().getAtlas("sprites/items.atlas");
|
||||
Sprite backSprite = atlas.createSprite("CardBack");
|
||||
Pixmap drawingMap = new Pixmap((int) backSprite.getWidth(), (int) backSprite.getHeight(), Pixmap.Format.RGBA8888);
|
||||
|
||||
DrawOnPixmap.draw(drawingMap, backSprite);
|
||||
Sprite gold = atlas.createSprite("Life");
|
||||
DrawOnPixmap.draw(drawingMap, (int) ((backSprite.getWidth() / 2f) - gold.getWidth() / 2f), (int) ((backSprite.getHeight() / 4f) * 1f), gold);
|
||||
DrawOnPixmap.drawText(drawingMap, String.valueOf(reward.getCount()), 0, (int) ((backSprite.getHeight() / 4f) * 2f), backSprite.getWidth());
|
||||
|
||||
image = new Texture(drawingMap);
|
||||
drawingMap.dispose();
|
||||
needsToBeDisposed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
if(flipOnClick)
|
||||
flip();
|
||||
}
|
||||
@Override
|
||||
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor){
|
||||
hover=true;
|
||||
}
|
||||
@Override
|
||||
public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor){
|
||||
hover=false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setCardImage(Texture img) {
|
||||
image=img;
|
||||
image.setFilter(Texture.TextureFilter.Linear,Texture.TextureFilter.Linear);
|
||||
TextureRegionDrawable drawable=new TextureRegionDrawable(new TextureRegion(image));
|
||||
drawable.setMinSize((Scene.GetIntendedHeight()/ RewardScene.CARD_WIDTH_TO_HEIGHT)*0.95f,Scene.GetIntendedHeight()*0.95f);
|
||||
toolTipImage=new Image(drawable);
|
||||
tooltip=new Tooltip<Image>(toolTipImage);
|
||||
tooltip.setInstant(true);
|
||||
if(frontSideUp())
|
||||
addListener(tooltip);
|
||||
}
|
||||
|
||||
private boolean frontSideUp() {
|
||||
return (flipProcess >= 0.5f) == flipOnClick;
|
||||
}
|
||||
|
||||
public boolean isFlipped() {
|
||||
|
||||
return (clicked&&flipProcess>=1);
|
||||
}
|
||||
public void flip() {
|
||||
|
||||
if(clicked)
|
||||
return;
|
||||
clicked=true;
|
||||
flipProcess=0;
|
||||
}
|
||||
@Override
|
||||
public void act(float delta)
|
||||
{
|
||||
super.act(delta);
|
||||
if(clicked)
|
||||
{
|
||||
if(flipProcess<1)
|
||||
flipProcess+=delta;
|
||||
else
|
||||
flipProcess=1;
|
||||
|
||||
if(tooltip!=null&&frontSideUp()&&!getListeners().contains(tooltip,true))
|
||||
addListener(tooltip);
|
||||
// flipProcess=(float)Gdx.input.getX()/ (float)Gdx.graphics.getWidth();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void draw (Batch batch, float parentAlpha) {
|
||||
|
||||
applyTransform(batch, computeTransform(batch.getTransformMatrix().cpy()));
|
||||
|
||||
oldProjectionTransform.set(batch.getProjectionMatrix());
|
||||
applyProjectionMatrix(batch);
|
||||
|
||||
|
||||
if(hover)
|
||||
batch.setColor(0.5f,0.5f,0.5f,1);
|
||||
|
||||
if(!frontSideUp())
|
||||
{
|
||||
batch.draw(backTexture,-getWidth()/2,-getHeight()/2,getWidth(),getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
drawFrontSide(batch);
|
||||
}
|
||||
batch.setColor(1,1,1,1);
|
||||
resetTransform(batch);
|
||||
batch.setProjectionMatrix(oldProjectionTransform);
|
||||
}
|
||||
|
||||
private void drawFrontSide(Batch batch) {
|
||||
|
||||
float width;
|
||||
float x;
|
||||
if(flipOnClick)
|
||||
{
|
||||
width=-getWidth();
|
||||
x=-getWidth()/2+getWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
width=getWidth();
|
||||
x=-getWidth()/2;
|
||||
}
|
||||
|
||||
if (image != null)
|
||||
batch.draw(image,x,-getHeight()/2,width,getHeight());
|
||||
else
|
||||
batch.draw(ImageCache.defaultImage,x,-getHeight()/2,width,getHeight());
|
||||
switch (reward.getType())
|
||||
{
|
||||
case Card:
|
||||
|
||||
break;
|
||||
case Gold:
|
||||
break;
|
||||
case Item:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyProjectionMatrix(Batch batch) {
|
||||
|
||||
final Vector3 direction = new Vector3(0, 0, -1);
|
||||
final Vector3 up = new Vector3(0, 1, 0);
|
||||
//final Vector3 position = new Vector3( getX()+getWidth()/2 , getY()+getHeight()/2, 0);
|
||||
final Vector3 position = new Vector3( Scene.GetIntendedWidth() /2f , Scene.GetIntendedHeight()/2f, 0);
|
||||
|
||||
float fov=67;
|
||||
Matrix4 projection=new Matrix4();
|
||||
Matrix4 view=new Matrix4();
|
||||
float hy= Scene.GetIntendedHeight()/2f;
|
||||
float a= (float) ((hy)/Math.sin(MathUtils.degreesToRadians*(fov/2f)));
|
||||
float height= (float) Math.sqrt((a*a)-(hy*hy));
|
||||
position.z=height*1f;
|
||||
float far=height*2f;
|
||||
float near=height*0.8f;
|
||||
|
||||
float aspect = (float)Scene.GetIntendedWidth() / (float)Scene.GetIntendedHeight();
|
||||
projection.setToProjection(Math.abs(near), Math.abs(far), fov, aspect);
|
||||
view.setToLookAt(position, position.cpy().add(direction), up);
|
||||
Matrix4.mul(projection.val, view.val);
|
||||
|
||||
batch.setProjectionMatrix(projection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final Matrix4 computedTransform = new Matrix4();
|
||||
private final Matrix4 oldTransform = new Matrix4();
|
||||
private final Matrix4 oldProjectionTransform = new Matrix4();
|
||||
|
||||
protected void applyTransform (Batch batch, Matrix4 transform)
|
||||
{
|
||||
oldTransform.set(batch.getTransformMatrix());
|
||||
batch.setTransformMatrix(transform);
|
||||
}
|
||||
|
||||
/** Restores the batch transform to what it was before {@link #applyTransform(Batch, Matrix4)}. Note this causes the batch to
|
||||
* be flushed. */
|
||||
protected void resetTransform (Batch batch) {
|
||||
batch.setTransformMatrix(oldTransform);
|
||||
}
|
||||
protected Matrix4 computeTransform (Matrix4 worldTransform) {
|
||||
|
||||
|
||||
float[] val=worldTransform.getValues();
|
||||
//val[Matrix4.M32]=0.0002f;
|
||||
worldTransform.set(val);
|
||||
float originX = this.getOriginX(), originY = this.getOriginY();
|
||||
worldTransform.translate(getX()+getWidth()/2 , getY()+getHeight()/2,0);
|
||||
if(clicked)
|
||||
{
|
||||
worldTransform.rotate(0,1,0,180*flipProcess);
|
||||
}
|
||||
computedTransform.set(worldTransform);
|
||||
return computedTransform;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* Interface to save the content the the save game file
|
||||
*/
|
||||
public interface SaveFileContent {
|
||||
void writeToSaveFile(ObjectOutputStream saveFile) throws IOException ;
|
||||
void readFromSaveFile(ObjectInputStream saveFile) throws IOException, ClassNotFoundException;
|
||||
}
|
||||
109
forge-adventure/src/main/java/forge/adventure/util/Selector.java
Normal file
109
forge-adventure/src/main/java/forge/adventure/util/Selector.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
|
||||
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 com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
|
||||
/**
|
||||
* UI element to click through options, can be configured in an UiActor
|
||||
*/
|
||||
public class Selector extends Group {
|
||||
private final ImageButton leftArrow;
|
||||
private final ImageButton rightArrow;
|
||||
private final TextButton label;
|
||||
private int currentIndex = 0;
|
||||
private Array<String> textList;
|
||||
|
||||
|
||||
public Selector() {
|
||||
ImageButton.ImageButtonStyle leftArrowStyle = Controls.GetSkin().get("leftarrow", ImageButton.ImageButtonStyle.class);
|
||||
leftArrow = new ImageButton(leftArrowStyle);
|
||||
|
||||
ImageButton.ImageButtonStyle rightArrowStyle = Controls.GetSkin().get("rightarrow", ImageButton.ImageButtonStyle.class);
|
||||
rightArrow = new ImageButton(rightArrowStyle);
|
||||
|
||||
label = new TextButton("", Controls.GetSkin());
|
||||
addActor(leftArrow);
|
||||
addActor(rightArrow);
|
||||
addActor(label);
|
||||
leftArrow.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
try {
|
||||
setCurrentIndex(currentIndex - 1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
rightArrow.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
try {
|
||||
setCurrentIndex(currentIndex + 1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sizeChanged() {
|
||||
super.sizeChanged();
|
||||
|
||||
leftArrow.setWidth(getHeight());
|
||||
leftArrow.setHeight(getHeight());
|
||||
rightArrow.setWidth(getHeight());
|
||||
rightArrow.setHeight(getHeight());
|
||||
label.setHeight(getHeight());
|
||||
label.setX(getHeight());
|
||||
label.setWidth(getWidth() - (getHeight() * 2));
|
||||
rightArrow.setX(getWidth() - getHeight());
|
||||
}
|
||||
|
||||
public int getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
public void setCurrentIndex(int currentIndex) {
|
||||
currentIndex %= textList.size;
|
||||
if (currentIndex < 0) {
|
||||
currentIndex += textList.size;
|
||||
}
|
||||
int oldIndex = currentIndex;
|
||||
this.currentIndex = currentIndex;
|
||||
label.setText(textList.get(currentIndex));
|
||||
ChangeListener.ChangeEvent changeEvent = Pools.obtain(ChangeListener.ChangeEvent.class);
|
||||
if (fire(changeEvent)) {
|
||||
this.currentIndex = oldIndex;
|
||||
label.setText(textList.get(currentIndex));
|
||||
}
|
||||
Pools.free(changeEvent);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return textList.get(currentIndex);
|
||||
}
|
||||
|
||||
public Array<String> getTextList() {
|
||||
return textList;
|
||||
}
|
||||
|
||||
public void setTextList(Array<String> textList) {
|
||||
this.textList = textList;
|
||||
setCurrentIndex(currentIndex);
|
||||
}
|
||||
|
||||
public void setTextList(String[] strings) {
|
||||
this.textList = new Array<>(strings);
|
||||
setCurrentIndex(currentIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.PixmapIO;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* Abstract class to serialize other objects.
|
||||
*/
|
||||
public abstract class Serializer {
|
||||
|
||||
|
||||
static public void WritePixmap(java.io.ObjectOutputStream out, Pixmap pixmap) throws IOException {
|
||||
|
||||
if (pixmap != null) {
|
||||
PixmapIO.PNG png = new PixmapIO.PNG();
|
||||
png.setFlipY(false);
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
png.write(stream, pixmap);
|
||||
byte[] data = stream.toByteArray();
|
||||
out.writeInt(data.length);
|
||||
out.write(data);
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
static public Pixmap ReadPixmap(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
|
||||
int length = in.readInt();
|
||||
if (length == 0)
|
||||
return new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||
|
||||
byte[] data = new byte[length];
|
||||
in.readFully(data, 0, length);
|
||||
|
||||
return new Pixmap(data, 0, length);
|
||||
|
||||
}
|
||||
|
||||
public static void WritePixmap(ObjectOutputStream out, Pixmap pixmap, boolean b) throws IOException {
|
||||
if (pixmap != null) {
|
||||
PixmapIO.PNG png = new PixmapIO.PNG();
|
||||
png.setFlipY(b);
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
png.write(stream, pixmap);
|
||||
byte[] data = stream.toByteArray();
|
||||
out.writeInt(data.length);
|
||||
out.write(data);
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeVector(ObjectOutputStream out,Vector2 position) throws IOException {
|
||||
out.writeFloat(position.x);
|
||||
out.writeFloat(position.y);
|
||||
}
|
||||
public static void readVector(ObjectInputStream in, Vector2 position) throws IOException {
|
||||
float x=in.readFloat();
|
||||
position.set(x,in.readFloat());
|
||||
}
|
||||
|
||||
public static void writeRectangle(ObjectOutputStream out,Rectangle rectangle) throws IOException {
|
||||
out.writeFloat(rectangle.x);
|
||||
out.writeFloat(rectangle.y);
|
||||
out.writeFloat(rectangle.width);
|
||||
out.writeFloat(rectangle.height);
|
||||
}
|
||||
public static void readRectangle(ObjectInputStream in, Rectangle rectangle) throws IOException {
|
||||
float x=in.readFloat();
|
||||
float y=in.readFloat();
|
||||
float w=in.readFloat();
|
||||
float h=in.readFloat();
|
||||
rectangle.set(x,y,w,h);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/**
|
||||
* List of function points to inform all listeners, maybe redesign to a more java like approach
|
||||
*/
|
||||
public class SignalList extends Array<Runnable> {
|
||||
public void emit() {
|
||||
|
||||
for(Runnable signal:this) {
|
||||
try {
|
||||
signal.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.maps.ImageResolver;
|
||||
import com.badlogic.gdx.maps.MapObjects;
|
||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.XmlReader;
|
||||
|
||||
/**
|
||||
* Rewritten the loadObject method of TmxMapLoader to support templates in tiled map.
|
||||
*
|
||||
*/
|
||||
public class TemplateTmxMapLoader extends TmxMapLoader {
|
||||
|
||||
FileHandle tmxFile;
|
||||
|
||||
@Override
|
||||
protected TiledMap loadTiledMap(FileHandle tmxFile, TmxMapLoader.Parameters parameter, ImageResolver imageResolver) {
|
||||
this.tmxFile = tmxFile;
|
||||
return super.loadTiledMap(tmxFile, parameter, imageResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadObject(TiledMap map, MapObjects objects, XmlReader.Element element, float heightInPixels) {
|
||||
if (element.getName().equals("object")) {
|
||||
|
||||
if (!element.hasAttribute("template")) {
|
||||
super.loadObject(map, objects, element, heightInPixels);
|
||||
return;
|
||||
}
|
||||
FileHandle template = getRelativeFileHandle(tmxFile, element.getAttribute("template"));
|
||||
XmlReader.Element el = xml.parse(template);
|
||||
for (XmlReader.Element obj : new Array.ArrayIterator<>(el.getChildrenByName("object"))) {
|
||||
for(ObjectMap.Entry<String, String> attr: new ObjectMap.Entries<>(element.getAttributes()))
|
||||
{
|
||||
obj.setAttribute(attr.key, attr.value);
|
||||
}
|
||||
XmlReader.Element properties = element.getChildByName("properties");
|
||||
XmlReader.Element templateProperties = obj.getChildByName("properties");
|
||||
if (properties != null&&templateProperties!=null)
|
||||
{
|
||||
for( XmlReader.Element propertyElements : new Array.ArrayIterator<>(properties.getChildrenByName("property")))
|
||||
{
|
||||
templateProperties.addChild(propertyElements);
|
||||
}
|
||||
}
|
||||
super.loadObject(map, objects, obj, heightInPixels);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
192
forge-adventure/src/main/java/forge/adventure/util/UIActor.java
Normal file
192
forge-adventure/src/main/java/forge/adventure/util/UIActor.java
Normal file
@@ -0,0 +1,192 @@
|
||||
package forge.adventure.util;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
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;
|
||||
import forge.adventure.data.UIData;
|
||||
|
||||
/**
|
||||
* Group of controls that will be loaded from a configuration file
|
||||
*/
|
||||
public class UIActor extends Group {
|
||||
UIData data;
|
||||
|
||||
public UIActor(FileHandle handle) {
|
||||
data = (new Json()).fromJson(UIData.class, handle);
|
||||
|
||||
setWidth(data.width);
|
||||
setHeight(data.height);
|
||||
|
||||
for (OrderedMap<String, String> element : new Array.ArrayIterator<>(data.elements)) {
|
||||
String type = element.get("type");
|
||||
Actor newActor;
|
||||
if(type==null)
|
||||
{
|
||||
newActor=new Actor();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (type) {
|
||||
case "Selector":
|
||||
newActor = new Selector();
|
||||
readSelectorProperties((Selector) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "Label":
|
||||
newActor = new Label("", Controls.GetSkin());
|
||||
readLabelProperties((Label) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "Image":
|
||||
newActor = new Image();
|
||||
readImageProperties((Image) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "ImageButton":
|
||||
newActor = new ImageButton(Controls.GetSkin());
|
||||
readImageButtonProperties((ImageButton) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "Window":
|
||||
newActor = new Window("", Controls.GetSkin());
|
||||
readWindowProperties((Window) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "TextButton":
|
||||
newActor = new TextButton("", Controls.GetSkin());
|
||||
readButtonProperties((TextButton) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "TextField":
|
||||
newActor = new TextField("", Controls.GetSkin());
|
||||
readTextFieldProperties((TextField) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
case "Scroll":
|
||||
newActor = new ScrollPane(null, Controls.GetSkin());
|
||||
readScrollPaneProperties((ScrollPane) newActor, new OrderedMap.OrderedMapEntries<>(element));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + type);
|
||||
}
|
||||
}
|
||||
//load Actor Properties
|
||||
float yValue = 0;
|
||||
for (ObjectMap.Entry property : new OrderedMap.OrderedMapEntries<>(element)) {
|
||||
switch (property.key.toString()) {
|
||||
case "width":
|
||||
newActor.setWidth((Float) property.value);
|
||||
break;
|
||||
case "height":
|
||||
newActor.setHeight((Float) property.value);
|
||||
if (data.yDown)
|
||||
newActor.setY(data.height - yValue - newActor.getHeight());
|
||||
break;
|
||||
case "x":
|
||||
newActor.setX((Float) property.value);
|
||||
break;
|
||||
case "y":
|
||||
yValue = (Float) property.value;
|
||||
newActor.setY(data.yDown ? data.height - yValue - newActor.getHeight() : yValue);
|
||||
break;
|
||||
case "name":
|
||||
newActor.setName((String) property.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
addActor(newActor);
|
||||
}
|
||||
}
|
||||
|
||||
private void readScrollPaneProperties(ScrollPane newActor, ObjectMap.Entries<String, String> entries) {
|
||||
newActor.setActor(new Label("",Controls.GetSkin()));
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "style":
|
||||
newActor.setStyle(Controls.GetSkin().get(property.value.toString(), ScrollPane.ScrollPaneStyle.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void readWindowProperties(Window newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "style":
|
||||
newActor.setStyle(Controls.GetSkin().get(property.value.toString(), Window.WindowStyle.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readTextFieldProperties(TextField newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "text":
|
||||
newActor.setText(property.value.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readImageButtonProperties(ImageButton newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "style":
|
||||
newActor.setStyle(Controls.GetSkin().get(property.value.toString(), ImageButton.ImageButtonStyle.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readLabelProperties(Label newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "text":
|
||||
newActor.setText(property.value.toString());
|
||||
break;
|
||||
case "font":
|
||||
Label.LabelStyle style = new Label.LabelStyle(newActor.getStyle());
|
||||
style.font = Controls.GetSkin().getFont(property.value.toString());
|
||||
newActor.setStyle(style);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readSelectorProperties(Selector newActor, ObjectMap.Entries<String, String> entries) {
|
||||
}
|
||||
|
||||
private void readButtonProperties(TextButton newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "text":
|
||||
newActor.setText(property.value.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readImageProperties(Image newActor, ObjectMap.Entries<String, String> entries) {
|
||||
for (ObjectMap.Entry property : entries) {
|
||||
switch (property.key.toString()) {
|
||||
case "image":
|
||||
newActor.setDrawable(new TextureRegionDrawable(new Texture(Config.instance().getFile(property.value.toString()))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onButtonPress(String name, Runnable func) {
|
||||
|
||||
Actor button = findActor(name);
|
||||
assert button != null;
|
||||
button.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
func.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import forge.adventure.data.DifficultyData;
|
||||
import forge.adventure.data.HeroListData;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Reward;
|
||||
import forge.adventure.util.SaveFileContent;
|
||||
import forge.adventure.util.SignalList;
|
||||
import forge.deck.Deck;
|
||||
import forge.item.PaperCard;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that represents the player (not the player sprite)
|
||||
*/
|
||||
public class AdventurePlayer implements Serializable, Disposable, SaveFileContent {
|
||||
private Deck deck;
|
||||
private int avatarIndex;
|
||||
private int heroRace;
|
||||
private boolean isFemale;
|
||||
private float worldPosX;
|
||||
private float worldPosY;
|
||||
private String name;
|
||||
private int gold=0;
|
||||
private int maxLife=20;
|
||||
private int life=20;
|
||||
private DifficultyData difficultyData;
|
||||
static public AdventurePlayer current()
|
||||
{
|
||||
return WorldSave.currentSave.getPlayer();
|
||||
}
|
||||
private List<PaperCard> cards=new ArrayList<>();
|
||||
|
||||
public void create(String n, Deck startingDeck, boolean male, int race, int avatar,DifficultyData difficultyData) {
|
||||
|
||||
deck = startingDeck;
|
||||
gold =difficultyData.staringMoney;
|
||||
cards.addAll(deck.getAllCardsInASinglePool().toFlatList());
|
||||
maxLife=difficultyData.startingLife;
|
||||
this.difficultyData=difficultyData;
|
||||
life=maxLife;
|
||||
avatarIndex = avatar;
|
||||
heroRace = race;
|
||||
isFemale = !male;
|
||||
name = n;
|
||||
onGoldChangeList.emit();
|
||||
onLifeTotalChangeList.emit();
|
||||
}
|
||||
|
||||
public Deck getDeck() {
|
||||
return deck;
|
||||
}
|
||||
public List<PaperCard> getCards() {
|
||||
return cards;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public float getWorldPosX() {
|
||||
return worldPosX;
|
||||
}
|
||||
|
||||
public void setWorldPosX(float worldPosX) {
|
||||
this.worldPosX = worldPosX;
|
||||
}
|
||||
|
||||
public float getWorldPosY() {
|
||||
return worldPosY;
|
||||
}
|
||||
|
||||
public void setWorldPosY(float worldPosY) {
|
||||
this.worldPosY = worldPosY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToSaveFile(java.io.ObjectOutputStream out) throws IOException {
|
||||
|
||||
|
||||
out.writeUTF(name);
|
||||
out.writeFloat(worldPosX);
|
||||
out.writeFloat(worldPosY);
|
||||
out.writeInt(avatarIndex);
|
||||
out.writeInt(heroRace);
|
||||
out.writeBoolean(isFemale);
|
||||
out.writeInt(gold);
|
||||
out.writeInt(life);
|
||||
out.writeInt(maxLife);
|
||||
out.writeObject(deck);
|
||||
out.writeObject(cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromSaveFile(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
name = in.readUTF();
|
||||
worldPosX = in.readFloat();
|
||||
worldPosY = in.readFloat();
|
||||
|
||||
avatarIndex = in.readInt();
|
||||
heroRace = in.readInt();
|
||||
isFemale = in.readBoolean();
|
||||
gold = in.readInt();
|
||||
life = in.readInt();
|
||||
maxLife = in.readInt();
|
||||
deck = (Deck) in.readObject();
|
||||
cards = (List) in.readObject();
|
||||
|
||||
|
||||
onLifeTotalChangeList.emit();
|
||||
onGoldChangeList.emit();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
public String spriteName() {
|
||||
return HeroListData.getHero(heroRace, isFemale);
|
||||
}
|
||||
|
||||
public FileHandle sprite() {
|
||||
return Config.instance().getFile(HeroListData.getHero(heroRace, isFemale));
|
||||
}
|
||||
|
||||
public TextureRegion avatar() {
|
||||
return HeroListData.getAvatar(heroRace, isFemale, avatarIndex);
|
||||
}
|
||||
|
||||
public void addReward(Reward reward) {
|
||||
|
||||
switch (reward.getType())
|
||||
{
|
||||
case Card:
|
||||
cards.add(reward.getCard());
|
||||
break;
|
||||
case Gold:
|
||||
addGold(reward.getCount());
|
||||
break;
|
||||
case Item:
|
||||
break;
|
||||
case Life:
|
||||
addMaxLife(reward.getCount());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SignalList onLifeTotalChangeList=new SignalList();
|
||||
SignalList onGoldChangeList=new SignalList();
|
||||
SignalList onPlayerChangeList=new SignalList();
|
||||
|
||||
private void addGold(int goldCount) {
|
||||
gold+=goldCount;
|
||||
onGoldChangeList.emit();
|
||||
}
|
||||
|
||||
public int getGold() {
|
||||
return gold;
|
||||
}
|
||||
|
||||
public void onLifeChange(Runnable o) {
|
||||
onLifeTotalChangeList.add(o);
|
||||
o.run();
|
||||
}
|
||||
public void onPlayerChanged(Runnable o) {
|
||||
onPlayerChangeList.add(o);
|
||||
o.run();
|
||||
}
|
||||
|
||||
public void onGoldChange(Runnable o) {
|
||||
onGoldChangeList.add(o);
|
||||
o.run();
|
||||
}
|
||||
|
||||
public int getLife() {
|
||||
return life;
|
||||
}
|
||||
|
||||
public int getMaxLife() {
|
||||
return maxLife;
|
||||
}
|
||||
|
||||
public void heal() {
|
||||
life=maxLife;
|
||||
onLifeTotalChangeList.emit();
|
||||
}
|
||||
public void defeated() {
|
||||
gold=gold/2;
|
||||
life=Math.max(1,(int)(life-(maxLife*0.2f)));
|
||||
onLifeTotalChangeList.emit();
|
||||
onGoldChangeList.emit();
|
||||
}
|
||||
public void addMaxLife(int count) {
|
||||
maxLife+=count;
|
||||
life+=count;
|
||||
onLifeTotalChangeList.emit();
|
||||
}
|
||||
public void takeGold(int price) {
|
||||
gold-=price;
|
||||
onGoldChangeList.emit();
|
||||
}
|
||||
|
||||
public DifficultyData getDifficulty() {
|
||||
return difficultyData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package forge.adventure.world;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import forge.adventure.data.BiomeSpriteData;
|
||||
import forge.adventure.util.Config;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* class to load and buffer map sprites
|
||||
*/
|
||||
public class BiomeSprites {
|
||||
private final HashMap<String, Array<Sprite>> spriteBuffer = new HashMap<>();
|
||||
public String textureAtlas;
|
||||
public BiomeSpriteData[] sprites;
|
||||
private TextureAtlas textureAtlasBuffer;
|
||||
|
||||
public Sprite getSprite(String name, int seed) {
|
||||
if (textureAtlasBuffer == null) {
|
||||
textureAtlasBuffer = Config.instance().getAtlas(textureAtlas);
|
||||
for (Texture texture : new ObjectSet.ObjectSetIterator<>(textureAtlasBuffer.getTextures())) {
|
||||
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||
}
|
||||
}
|
||||
if (!spriteBuffer.containsKey(name)) {
|
||||
spriteBuffer.put(name, new Array<Sprite>());
|
||||
}
|
||||
Array<Sprite> sprites = spriteBuffer.get(name);
|
||||
if (sprites.isEmpty()) {
|
||||
sprites.addAll(textureAtlasBuffer.createSprites(name));
|
||||
}
|
||||
return sprites.get(seed % sprites.size);
|
||||
}
|
||||
|
||||
public BiomeSpriteData getSpriteData(String name) {
|
||||
for (BiomeSpriteData data : sprites) {
|
||||
if (data.name.equals(name))
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user