Compare commits
8 Commits
master
...
title-scre
Author | SHA1 | Date | |
---|---|---|---|
|
22a744f65a | ||
|
c6de19cf19 | ||
|
c1a57f7d7a | ||
576cfed99f | |||
|
5af1b7309d | ||
|
0f0a94811f | ||
|
51bcca1499 | ||
|
ce9e95e5ce |
49
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
49
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,49 +0,0 @@
|
||||
name: Bug Report
|
||||
description: Let us know about a problem
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this template to report identified problems. If the game suddenly crashed, and you need help identifying the cause of a crashreport, please use the Investigate Crashreport template instead.
|
||||
|
||||
**Do not forget to give your issue a descriptive title.**
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
What did you do just before the problem appeared, or where can it be observed?
|
||||
|
||||
If the issue occurs unreliably, please estimate the probability of the crash.
|
||||
placeholder: |
|
||||
1. Look at a cow
|
||||
2. Wait for the cow to look back
|
||||
3. The cow turns away after a minute
|
||||
|
||||
The issue occurs approximately once every 10 attempts.
|
||||
|
||||
Player inventory must be empty. Does not occur in multiplayer. Occurred inside a virtual machine.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: |
|
||||
What should happen?
|
||||
placeholder: |
|
||||
The cow should stare back indefinitely, because obviously it should, and because comedy.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other information
|
||||
description: What else can you tell us about this bug?
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Crashreport
|
||||
description: If you have a relevant crashreport, paste the contents of the crashreport file here
|
||||
render: text
|
||||
validations:
|
||||
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Official Progressia Discord
|
||||
url: https://discord.gg/TWuXbVmX23
|
||||
about: Ask developers or community members for help
|
41
.github/ISSUE_TEMPLATE/crashreport.yml
vendored
41
.github/ISSUE_TEMPLATE/crashreport.yml
vendored
@ -1,41 +0,0 @@
|
||||
name: Investigate Crashreport
|
||||
description: Submit a crashreport to determine the problem
|
||||
labels: [bug, crashreport]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this template to submit crashreports for initial analisys. If you don't have a crashreport, or you have a good understanding of the underlying cause, please use the Bug Report template instead.
|
||||
|
||||
Crashreports can be found in `WORKING-DIRECTORY/crashreports` (take notice of the timestamp). `WORKING-DIRECTORY` is `C:\Users\<windows-user>\AppData\Roaming\Progressia` on Windows when using the installer.
|
||||
|
||||
**Do not forget to give your issue a descriptive title.**
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
What did you do just before the crash? How could someone else reproduce it? What other context might be relevant?
|
||||
|
||||
If the issue occurs unreliably, please estimate the probability of the crash.
|
||||
placeholder: |
|
||||
1. Enter a new world
|
||||
2. Turn around
|
||||
3. Wait 5 minutes
|
||||
4. Game crashes half of the time
|
||||
|
||||
Player inventory must be empty. Does not crash in multiplayer. Occurred inside a virtual machine.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other information
|
||||
description: What else can you tell us about this crashreport?
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Crashreport
|
||||
description: Paste the contents of the crashreport file here
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
159
build.gradle
159
build.gradle
@ -42,16 +42,6 @@ compileJava {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set encoding
|
||||
*/
|
||||
|
||||
compileJava {
|
||||
options.encoding = 'utf8'
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Dependencies
|
||||
*/
|
||||
@ -70,7 +60,7 @@ repositories {
|
||||
dependencies {
|
||||
// Google Guava
|
||||
// A generic utilities library
|
||||
implementation 'com.google.guava:guava:31.0.1-jre'
|
||||
implementation 'com.google.guava:guava:30.0-jre'
|
||||
|
||||
// Trove4j
|
||||
// Provides optimized Collections for primitive types
|
||||
@ -83,8 +73,8 @@ dependencies {
|
||||
|
||||
// Log4j
|
||||
// A logging library
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.17.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.17.0'
|
||||
|
||||
// JUnit
|
||||
// A unit-testing library
|
||||
@ -173,21 +163,17 @@ task resolveVersion {
|
||||
description 'Resolves version information from Git repository or project properties.'
|
||||
|
||||
doFirst {
|
||||
|
||||
project.ext.commit = System.env.GIT_COMMIT
|
||||
project.ext.branch = System.env.GIT_BRANCH
|
||||
|
||||
try {
|
||||
def git = Grgit.open(dir: project.projectDir)
|
||||
|
||||
project.ext.commit = commit ?: git.head().id
|
||||
project.ext.branch = branch ?: git.branch.current().name
|
||||
project.ext.commit = git.head().id
|
||||
project.ext.branch = git.branch.current().name
|
||||
|
||||
if (project.version != 'unspecified') {
|
||||
// Leave version as-is
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve version from Git
|
||||
def tag = version_findRelevantTag(git)
|
||||
if (tag == null) {
|
||||
|
||||
@ -206,52 +192,20 @@ task resolveVersion {
|
||||
project.version = version_parseVersion(tag.name, tag.commit != git.head())
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
|
||||
if (project.version == 'unspecified') project.version = 'dev'
|
||||
project.ext.commit = commit ?: '-'
|
||||
project.ext.branch = branch ?: '-'
|
||||
project.ext.commit = '-'
|
||||
project.ext.branch = '-'
|
||||
|
||||
logger.warn 'No Git repository found in project root, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
|
||||
}
|
||||
|
||||
if (branch.contains '/') {
|
||||
// Strip remote - no one wants that
|
||||
project.ext.branch = branch.takeAfter '/'
|
||||
}
|
||||
|
||||
if (!project.hasProperty('buildId')) {
|
||||
project.ext.buildId = '-'
|
||||
}
|
||||
}
|
||||
|
||||
doLast {
|
||||
|
||||
if (!project.hasProperty('buildId')) {
|
||||
project.ext.buildId = '-'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Apply LWJGL logic
|
||||
*/
|
||||
apply from: 'build_logic/lwjgl.gradle'
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copy libraries into build/libs/lib directory, next to Progressia.jar
|
||||
*/
|
||||
|
||||
task exportLibs(type: Sync) {
|
||||
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
||||
|
||||
jar.dependsOn exportLibs
|
||||
dependsOn lwjgl_addNativesToRuntimeOnly
|
||||
|
||||
// from defined in configureManifest
|
||||
into 'build/libs/lib'
|
||||
}
|
||||
|
||||
|
||||
@ -265,16 +219,11 @@ task configureManifest {
|
||||
|
||||
jar.dependsOn configureManifest
|
||||
dependsOn resolveVersion
|
||||
dependsOn lwjgl_addNativesToRuntimeOnly
|
||||
|
||||
doFirst {
|
||||
def classPath = project.lwjgl.replaceNativesIn(configurations.runtimeClasspath)
|
||||
|
||||
exportLibs.from classPath
|
||||
|
||||
jar.manifest.attributes(
|
||||
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
|
||||
'Class-Path': classPath.collect { "lib/${java.net.URLEncoder.encode it.name}" } .join(' '),
|
||||
'Class-Path': configurations.runtimeClasspath.collect { "lib/${it.name}" } .join(' '),
|
||||
|
||||
'Specification-Title': 'Progressia',
|
||||
|
||||
@ -289,6 +238,28 @@ task configureManifest {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copy libraries into buil/libs/lib directory, next to Progressia.jar
|
||||
*/
|
||||
|
||||
task exportLibs(type: Sync) {
|
||||
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
||||
|
||||
jar.dependsOn exportLibs
|
||||
|
||||
from configurations.runtimeClasspath
|
||||
into 'build/libs/lib'
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Apply LWJGL logic
|
||||
*/
|
||||
apply from: 'build_logic/lwjgl.gradle'
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Packaging working directory configuration
|
||||
*/
|
||||
@ -296,40 +267,64 @@ task configureManifest {
|
||||
import java.nio.file.*
|
||||
import java.nio.file.attribute.*
|
||||
|
||||
task deletePackagingDirs(type: Delete) {
|
||||
description 'Deletes build/tmp/packaging directory.'
|
||||
followSymlinks = false
|
||||
delete 'build/tmp/packaging'
|
||||
task createPackagingDirs() {
|
||||
description 'Resets build/tmp/packaging directory.'
|
||||
|
||||
doLast {
|
||||
def tmpDir = buildDir.toPath().resolve 'tmp/packaging'
|
||||
|
||||
def nuke = new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
|
||||
if (e == null) {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
} else {
|
||||
// directory iteration failed
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task linkBuildOutputForPackaging {
|
||||
// Fckn nuke tmpDir from orbit
|
||||
// I'm so done with deleting file trees in Java/Groovy/whatever
|
||||
// ...Not using File.deleteDir() because the latter recurses into symlinks, and we don't want to wipe build/libs/lib
|
||||
if (Files.exists(tmpDir)) {
|
||||
Files.walkFileTree tmpDir, nuke
|
||||
}
|
||||
|
||||
Files.createDirectories tmpDir.resolve('workingDir')
|
||||
Files.createDirectories buildDir.toPath().resolve('packages')
|
||||
}
|
||||
}
|
||||
|
||||
task linkBuildOutputForPackaging() {
|
||||
description 'Symlinks the contents of build/libs into packaging working directory.'
|
||||
|
||||
dependsOn build
|
||||
mustRunAfter deletePackagingDirs
|
||||
dependsOn createPackagingDirs
|
||||
|
||||
onlyIf { preparePackaging.ext.mode == 'symlink' }
|
||||
|
||||
ext.from = 'build/libs'
|
||||
ext.into = "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
|
||||
|
||||
inputs.dir from
|
||||
outputs.dir into
|
||||
|
||||
doLast {
|
||||
def fromPath = Paths.get from
|
||||
def intoPath = Paths.get into
|
||||
def from = buildDir.toPath().resolve 'libs'
|
||||
def into = buildDir.toPath().resolve "tmp/packaging/workingDir/${preparePackaging.ext.buildDest}"
|
||||
|
||||
Files.createDirectories intoPath
|
||||
Files.createDirectories into
|
||||
|
||||
Files.list(fromPath).each {
|
||||
Files.list(from).each {
|
||||
def fileName = it.fileName.toString()
|
||||
|
||||
// Exclude all JARs except the current one
|
||||
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
|
||||
return
|
||||
|
||||
Files.createSymbolicLink intoPath.resolve(it.fileName), intoPath.relativize(it)
|
||||
Files.createSymbolicLink into.resolve(it.fileName), it
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -338,7 +333,7 @@ task copyBuildOutputForPackaging(type: Copy) {
|
||||
description 'Copies the contents of build/libs into packaging working directory.'
|
||||
|
||||
dependsOn build
|
||||
mustRunAfter deletePackagingDirs
|
||||
dependsOn createPackagingDirs
|
||||
|
||||
onlyIf { preparePackaging.ext.mode == 'copy' }
|
||||
|
||||
@ -353,7 +348,7 @@ task preparePackaging {
|
||||
preparePackaging.ext.buildDest = ''
|
||||
preparePackaging.ext.mode = 'symlink'
|
||||
|
||||
dependsOn deletePackagingDirs
|
||||
dependsOn createPackagingDirs
|
||||
dependsOn linkBuildOutputForPackaging
|
||||
dependsOn copyBuildOutputForPackaging
|
||||
}
|
||||
|
@ -6,14 +6,14 @@
|
||||
project.ext.lwjgl = new HashMap<>()
|
||||
|
||||
// Version of LWJGL
|
||||
lwjgl.version = '3.3.0'
|
||||
lwjgl.version = '3.2.3'
|
||||
|
||||
/*
|
||||
* Target platforms for current operation.
|
||||
* This is filled in by the request* tasks. This is referenced by the addLwjglNatives task.
|
||||
* When empty, current platform is assumed.
|
||||
*/
|
||||
lwjgl.targets = new HashSet<String>()
|
||||
lwjgl.targets = new HashSet<>()
|
||||
|
||||
// LWJGL components. To include org.lwjgl:lwjgl-foobar, add 'foobar' to this list.
|
||||
lwjgl.libraries = [
|
||||
@ -33,49 +33,34 @@ switch (OperatingSystem.current()) {
|
||||
: 'linux'
|
||||
break
|
||||
case OperatingSystem.MAC_OS:
|
||||
lwjgl.localArch = System.getProperty('os.arch').startsWith('aarch64') ? 'macos-arm64' : 'macos'
|
||||
lwjgl.localArch = 'macos'
|
||||
break
|
||||
case OperatingSystem.WINDOWS:
|
||||
def osArch = System.getProperty('os.arch')
|
||||
lwjgl.localArch = osArch.contains('64')
|
||||
? "windows${osArch.startsWith('aarch64') ? '-arm64' : ''}"
|
||||
: 'windows-x86'
|
||||
lwjgl.localArch = System.getProperty('os.arch').contains('64') ? 'windows' : 'windows-x86'
|
||||
break
|
||||
default:
|
||||
logger.info "Unknown or unsupported OS type according to Gradle's org.gradle.internal.os.OperatingSystem: ${OperatingSystem.current()}"
|
||||
break
|
||||
}
|
||||
|
||||
configurations {
|
||||
create 'lwjglNatives'
|
||||
}
|
||||
|
||||
// Declare pure-Java dependencies
|
||||
dependencies {
|
||||
// BOM
|
||||
|
||||
def bom = platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
|
||||
implementation bom
|
||||
lwjglNatives bom
|
||||
implementation platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
|
||||
|
||||
// Core
|
||||
implementation 'org.lwjgl:lwjgl'
|
||||
// Local natives for core
|
||||
runtimeOnly "org.lwjgl:lwjgl::natives-${lwjgl.localArch}"
|
||||
|
||||
// Components
|
||||
lwjgl.libraries.each { lib ->
|
||||
implementation "org.lwjgl:lwjgl-$lib"
|
||||
// Local natives for component
|
||||
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-${lwjgl.localArch}"
|
||||
}
|
||||
|
||||
lwjgl.libraries.each { implementation "org.lwjgl:lwjgl-$it" }
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds LWJGL native libraries to lwjglNatives configuration
|
||||
* Adds LWJGL native libraries to runtimeOnly configuration
|
||||
*/
|
||||
task lwjgl_addNativesToRuntimeOnly {
|
||||
// Make sure runtimeOnly has not been resolved
|
||||
compileJava.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||
configureManifest.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||
exportLibs.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||
|
||||
doFirst {
|
||||
if (project.hasProperty('forceTargets')) {
|
||||
try {
|
||||
@ -97,34 +82,17 @@ task lwjgl_addNativesToRuntimeOnly {
|
||||
logger.info 'Adding LWJGL native dependencies for platforms: {}', lwjgl.targets.sort().join(', ')
|
||||
}
|
||||
|
||||
if (lwjgl.targets.contains(null)) {
|
||||
if (lwjgl.localArch != null) {
|
||||
throw new GradleException("Requested local LWJGL natives; could not determine local architecture for OS ${OperatingSystem.current()} with os.arch ${System.getProperty('os.arch')}")
|
||||
} else {
|
||||
throw new GradleException("LWJGL targets resolved to ${lwjgl.targets}")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
lwjgl.targets.each { target ->
|
||||
lwjglNatives "org.lwjgl:lwjgl::natives-$target"
|
||||
runtimeOnly "org.lwjgl:lwjgl::natives-$target"
|
||||
lwjgl.libraries.each { lib ->
|
||||
lwjglNatives "org.lwjgl:lwjgl-$lib::natives-$target"
|
||||
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-$target"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces LWJGL natives in the given configuration with the requested ones
|
||||
lwjgl.replaceNativesIn = { config ->
|
||||
new ArrayList<File>().tap {
|
||||
addAll config
|
||||
removeIf { it.name ==~ /.*lwjgl.*natives.*/ }
|
||||
addAll project.configurations.lwjglNatives
|
||||
}
|
||||
}
|
||||
|
||||
task requestCrossPlatformDependencies {
|
||||
description 'Adds LWJGL natives for all available platforms.'
|
||||
|
||||
@ -145,5 +113,5 @@ def requestTask(String name, String... targets) {
|
||||
}
|
||||
|
||||
requestTask 'Linux', 'linux', 'linux-arm32', 'linux-arm64'
|
||||
requestTask 'Windows', 'windows', 'windows-arm64', 'windows-x86'
|
||||
requestTask 'MacOS', 'macos', 'macos-arm64'
|
||||
requestTask 'Windows', 'windows', 'windows-x86'
|
||||
requestTask 'MacOS', 'macos'
|
||||
|
@ -15,7 +15,7 @@ task packageDeb_configure() {
|
||||
preparePackaging.mustRunAfter packageDeb_configure
|
||||
|
||||
doLast {
|
||||
tasks.preparePackaging.ext.buildDest = 'usr/share/progressia'
|
||||
tasks.preparePackaging.ext.buildDest = '/usr/share/progressia'
|
||||
tasks.preparePackaging.ext.mode = 'copy'
|
||||
}
|
||||
}
|
||||
@ -31,10 +31,6 @@ task packageDeb(type: Exec) {
|
||||
|
||||
dependsOn packageDeb_processResources
|
||||
|
||||
doFirst {
|
||||
mkdir 'build/packages'
|
||||
}
|
||||
|
||||
executable 'dpkg-deb'
|
||||
args '--root-owner-group'
|
||||
args '--build', 'build/tmp/packaging/workingDir'
|
||||
|
@ -40,10 +40,6 @@ task packageNsis(type: Exec) {
|
||||
dependsOn packageNsis_generateIcon
|
||||
dependsOn packageNsis_generateLeftSide
|
||||
|
||||
doFirst {
|
||||
mkdir 'build/packages'
|
||||
}
|
||||
|
||||
executable 'makensis'
|
||||
args '-NOCONFIG'
|
||||
args "-DPROJECT_NAME=${project.name}"
|
||||
|
@ -36,10 +36,6 @@ task packageZip(type: Zip) {
|
||||
archiveVersion = project.version
|
||||
}
|
||||
|
||||
doFirst {
|
||||
mkdir 'build/packages'
|
||||
}
|
||||
|
||||
from 'build/tmp/packaging/workingDir'
|
||||
destinationDirectory = file('build/packages')
|
||||
}
|
||||
|
@ -143,8 +143,8 @@ build.
|
||||
Some users might find the need to build for a specific set of platforms. Inclusion of GNU/Linux, Windows or MacOS
|
||||
dependencies individually can be controlled with the following arguments to the `./gradlew build` command:
|
||||
- `requestLinuxDependencies` requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included;
|
||||
- `requestWindowsDependencies` requests that `natives-windows`, `natives-windows-arm64` and `natives-windows-x86` binaries are included;
|
||||
- `requestMacOSDependencies` requests that `natives-macos`, `natives-macos-arm64` binaries are included.
|
||||
- `requestWindowsDependencies` requests that `natives-windows` and `natives-windows-x86` binaries are included;
|
||||
- `requestMacOSDependencies` requests that `natives-macos` binaries are included.
|
||||
These requests can be applied in any combination. For example, the following command produces a build containing only
|
||||
GNU/Linux and Windows natives:
|
||||
|
||||
|
@ -12,8 +12,8 @@ This document is a user's reference for the build script of Progressia. For a be
|
||||
- `packageDeb` – creates a Debian package. Incompatible with other `package` tasks.
|
||||
- `packageNsis` – creates a Windows NSIS installer. Incompatible with other `package` tasks.
|
||||
- `requestLinuxDependencies` – requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included when building.
|
||||
- `requestWindowsDependencies` – requests that `natives-windows`, `natives-windows-arm64` and `natives-windows-x86` binaries are included when building.
|
||||
- `requestMacOSDependencies` – requests that `natives-macos` and `natives-macos-arm64` binaries are included when building.
|
||||
- `requestWindowsDependencies` – requests that `natives-windows` and `natives-windows-x86` binaries are included when building.
|
||||
- `requestMacOSDependencies` – requests that `natives-macos` binaries are included when building.
|
||||
- `requestCrossPlatformDependencies` – requests that all binaries are included when building.
|
||||
|
||||
To execute a task, run `./gradlew <task-name>`.
|
||||
@ -60,21 +60,14 @@ In all other cases, a fallback dummy value is used for version, appended with bu
|
||||
|
||||
### Git metadata
|
||||
|
||||
Git commit is determined from `GIT_COMMIT` environment variable if it exists, or the state of the local Git
|
||||
repository, if any, or `-`.
|
||||
|
||||
Git branch is determined from `GIT_BRANCH` environment variable if it exists, or the state of the local Git
|
||||
repository, if any, or `-`.
|
||||
|
||||
The names of the environment variables are picked to assist Jenkins builds.
|
||||
Git commit and Git branch are correspond to the state of the local Git repository, if any. In case Git metadata is
|
||||
unavailable, `-` fallback is used for both fields.
|
||||
|
||||
### Build ID
|
||||
|
||||
Build ID uniquely identifies artifacts produced by automated build systems. Build ID must be provided explicitly; it
|
||||
is `-` unless specified otherwise.
|
||||
|
||||
The proposed scheme for naming build IDs is `<builder><build-system><build attempt no.>`. For example, builds
|
||||
executed by WindCorp Jenkins suite have build IDs like `WJ3` or `WJ142`.
|
||||
Build ID uniquely identifies artifacts produced by automated build systems. For example, builds executed by WindCorp
|
||||
Jenkins suite have build IDs like `WJ3` or `WJ142`. Build ID must be provided explicitly; it is `-` unless specified
|
||||
otherwise.
|
||||
|
||||
Build ID may be set with `buildId` project property. This may be done in a variety of ways, for example with command
|
||||
line argument `-PbuildId=WJ3`
|
||||
@ -101,12 +94,10 @@ detected current architecture.
|
||||
### Available targets
|
||||
|
||||
| Name | Task |
|
||||
|-----------------|------------------------------|
|
||||
|---------------|------------------------------|
|
||||
| `linux` | `requestLinuxDependencies` |
|
||||
| `linux-arm32` | `requestLinuxDependencies` |
|
||||
| `linux-arm64` | `requestLinuxDependencies` |
|
||||
| `windows` | `requestWindowsDependencies` |
|
||||
| `windows-arm64` | `requestWindowsDependencies` |
|
||||
| `windows-x86` | `requestWindowsDependencies` |
|
||||
| `macos` | `requestMacOSDependencies` |
|
||||
| `macos-arm64` | `requestMacOSDependencies` |
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
259
gradlew
vendored
259
gradlew
vendored
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -17,113 +17,78 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@ -132,7 +97,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@ -140,95 +105,79 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
25
gradlew.bat
vendored
25
gradlew.bat
vendored
@ -29,9 +29,6 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@ -40,7 +37,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@ -54,7 +51,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@ -64,14 +61,28 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
1
logs/game.log
Normal file
1
logs/game.log
Normal file
@ -0,0 +1 @@
|
||||
22:26:25.948 [Music Thread ] WARN ru.windcorp.progressia.test.TestMusicPlayer > No music found
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* JPUtil
|
||||
* Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.windcorp.jputil;
|
||||
|
||||
public class ConstantsMapException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -4298704891780063127L;
|
||||
|
||||
public ConstantsMapException() {
|
||||
|
||||
}
|
||||
|
||||
public ConstantsMapException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public ConstantsMapException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConstantsMapException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConstantsMapException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
/*
|
||||
* JPUtil
|
||||
* Copyright (C) 2019-2022 OLEGSHA/Javapony and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.windcorp.jputil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class IntConstantsMap {
|
||||
|
||||
private final Map<Integer, String> namesByValue;
|
||||
private final Map<String, Integer> valuesByName;
|
||||
|
||||
protected IntConstantsMap(Map<Integer, String> namesByValue, Map<String, Integer> valuesByName) {
|
||||
this.namesByValue = namesByValue;
|
||||
this.valuesByName = valuesByName;
|
||||
}
|
||||
|
||||
public int getValue(String name) {
|
||||
Integer value = valuesByName.get(name);
|
||||
if (value == null) {
|
||||
throw new NoSuchElementException("No constant with name " + name);
|
||||
}
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
public boolean hasConstant(String name) {
|
||||
return valuesByName.containsKey(name);
|
||||
}
|
||||
|
||||
public String getName(int value) {
|
||||
String name = namesByValue.get(value);
|
||||
if (name == null) {
|
||||
throw new NoSuchElementException("No constant with value " + value);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean hasConstant(int value) {
|
||||
return namesByValue.containsKey(value);
|
||||
}
|
||||
|
||||
public Map<String, Integer> getAll() {
|
||||
return valuesByName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valuesByName.toString();
|
||||
}
|
||||
|
||||
public static Builder from(Class<?> clazz) {
|
||||
return new Builder(clazz);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface Filter {
|
||||
boolean test(String name, int value);
|
||||
}
|
||||
|
||||
public class ConstantSpec {
|
||||
public String name;
|
||||
public int value;
|
||||
|
||||
public void drop() {
|
||||
if (!extra.contains(name)) {
|
||||
name = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final List<Consumer<ConstantSpec>> transforms = new ArrayList<>();
|
||||
private final Set<String> extra = new HashSet<>();
|
||||
|
||||
private final Class<?> source;
|
||||
|
||||
public Builder(Class<?> source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Builder apply(Consumer<ConstantSpec> transform) {
|
||||
transforms.add(transform);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder only(Filter filter) {
|
||||
return apply(s -> {
|
||||
if (!filter.test(s.name, s.value)) {
|
||||
s.drop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Builder only(Predicate<String> nameFilter) {
|
||||
return apply(s -> {
|
||||
if (!nameFilter.test(s.name)) {
|
||||
s.drop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Builder onlyValued(IntPredicate valueFilter) {
|
||||
return apply(s -> {
|
||||
if (!valueFilter.test(s.value)) {
|
||||
s.drop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Builder regex(String regex) {
|
||||
return only(Pattern.compile(regex).asPredicate());
|
||||
}
|
||||
|
||||
public Builder prefix(String prefix) {
|
||||
return only(n -> n.startsWith(prefix) && n.length() > prefix.length());
|
||||
}
|
||||
|
||||
public Builder exclude(Filter filter) {
|
||||
return only((n, v) -> !filter.test(n, v));
|
||||
}
|
||||
|
||||
public Builder exclude(Predicate<String> nameFilter) {
|
||||
return only(nameFilter.negate());
|
||||
}
|
||||
|
||||
public Builder exclude(String... names) {
|
||||
Set<String> excluded = new HashSet<>();
|
||||
for (String name : names) {
|
||||
excluded.add(name);
|
||||
}
|
||||
return exclude(excluded::contains);
|
||||
}
|
||||
|
||||
public Builder excludeRegex(String... nameRegexes) {
|
||||
List<Predicate<String>> tests = new ArrayList<>();
|
||||
for (String regex : nameRegexes) {
|
||||
tests.add(Pattern.compile(regex).asPredicate());
|
||||
}
|
||||
return only((n, v) -> {
|
||||
for (Predicate<String> test : tests) {
|
||||
if (test.test(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public Builder extra(String... names) {
|
||||
for (String name : names) {
|
||||
extra.add(name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder rename(Function<String, String> renamer) {
|
||||
apply(s -> {
|
||||
s.name = renamer.apply(s.name);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder stripPrefix(String prefix) {
|
||||
return apply(s -> {
|
||||
if (s.name.startsWith(prefix)) {
|
||||
s.name = s.name.substring(prefix.length());
|
||||
} else if (extra.contains(s.name)) {
|
||||
return;
|
||||
} else {
|
||||
s.drop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public IntConstantsMap scan() {
|
||||
return build(true);
|
||||
}
|
||||
|
||||
public IntConstantsMap scanAll() {
|
||||
return build(false);
|
||||
}
|
||||
|
||||
private IntConstantsMap build(boolean onlyPublic) {
|
||||
Map<Integer, String> namesByValue = new HashMap<>();
|
||||
Map<String, Integer> valuesByName = new HashMap<>();
|
||||
|
||||
BiConsumer<String, Integer> putter = (name, value) -> {
|
||||
if (namesByValue.containsKey(value)) {
|
||||
throw newDuplicateException("value", value, name, namesByValue.get(value));
|
||||
}
|
||||
if (valuesByName.containsKey(name)) {
|
||||
throw newDuplicateException("name", name, value, valuesByName.get(name));
|
||||
}
|
||||
namesByValue.put(value, name);
|
||||
valuesByName.put(name, value);
|
||||
};
|
||||
|
||||
try {
|
||||
for (Field field : source.getDeclaredFields()) {
|
||||
processField(field, putter, onlyPublic);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ConstantsMapException(e);
|
||||
}
|
||||
|
||||
return new IntConstantsMap(
|
||||
Collections.unmodifiableMap(namesByValue),
|
||||
Collections.unmodifiableMap(valuesByName)
|
||||
);
|
||||
}
|
||||
|
||||
private void processField(Field field, BiConsumer<String, Integer> putter, boolean onlyPublic)
|
||||
throws IllegalAccessException {
|
||||
if (!Modifier.isStatic(field.getModifiers())) {
|
||||
return;
|
||||
}
|
||||
if (!Modifier.isFinal(field.getModifiers())) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean clearAccessible = false;
|
||||
if (!Modifier.isPublic(field.getModifiers())) {
|
||||
if (onlyPublic) {
|
||||
return;
|
||||
} else if (!isAccessibleFlagSet(field)) {
|
||||
field.setAccessible(true);
|
||||
clearAccessible = true;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
ConstantSpec spec = new ConstantSpec();
|
||||
spec.name = field.getName();
|
||||
spec.value = field.getInt(null);
|
||||
|
||||
for (Consumer<ConstantSpec> t : transforms) {
|
||||
t.accept(spec);
|
||||
if (spec.name == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
putter.accept(spec.name, spec.value);
|
||||
|
||||
} finally {
|
||||
if (clearAccessible) {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes, this method exists only so that neither Java 8 nor Java 9 complain about deprecation.
|
||||
*/
|
||||
@Deprecated
|
||||
private boolean isAccessibleFlagSet(Field f) {
|
||||
return f.isAccessible();
|
||||
}
|
||||
|
||||
private ConstantsMapException newDuplicateException(String what, Object common, Object current, Object old) {
|
||||
return new ConstantsMapException(
|
||||
String.format(
|
||||
"Duplicate %1$s: %2$s -> %3$s and %2$s -> %4$s",
|
||||
what,
|
||||
common,
|
||||
current,
|
||||
old
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,6 @@ import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
|
||||
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
|
||||
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
|
||||
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Atlases;
|
||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||
import ru.windcorp.progressia.client.localization.Localizer;
|
||||
@ -52,7 +51,6 @@ public class ClientProxy implements Proxy {
|
||||
throw CrashReports.report(e, "ClientProxy failed");
|
||||
}
|
||||
|
||||
ColorScheme.load(ResourceManager.getResource("assets/default.colorScheme"));
|
||||
Localizer.getInstance().setLanguage("en-US");
|
||||
|
||||
TestContent.registerContent();
|
||||
|
@ -34,7 +34,13 @@ public class Colors {
|
||||
DEBUG_BLUE = toVector(0xFF0000FF),
|
||||
DEBUG_CYAN = toVector(0xFF00FFFF),
|
||||
DEBUG_MAGENTA = toVector(0xFFFF00FF),
|
||||
DEBUG_YELLOW = toVector(0xFFFFFF00);
|
||||
DEBUG_YELLOW = toVector(0xFFFFFF00),
|
||||
|
||||
LIGHT_GRAY = toVector(0xFFCBCBD0),
|
||||
BLUE = toVector(0xFF37A2E6),
|
||||
HOVER_BLUE = toVector(0xFFC3E4F7),
|
||||
DISABLED_GRAY = toVector(0xFFE5E5E5),
|
||||
DISABLED_BLUE = toVector(0xFFB2D8ED);
|
||||
|
||||
public static Vec4 toVector(int argb) {
|
||||
return toVector(argb, new Vec4());
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2022 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.client.graphics.backend;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
|
||||
import ru.windcorp.jputil.ConstantsMapException;
|
||||
import ru.windcorp.jputil.IntConstantsMap;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
|
||||
public class GLFWErrorHandler {
|
||||
|
||||
private static final IntConstantsMap ERROR_CODES;
|
||||
|
||||
static {
|
||||
try {
|
||||
ERROR_CODES = IntConstantsMap.from(GLFW.class)
|
||||
.stripPrefix("GLFW_")
|
||||
.onlyValued(i -> i >= 0x10000 && i <= 0x1FFFF)
|
||||
.extra("GLFW_NO_ERROR")
|
||||
.scan();
|
||||
} catch (ConstantsMapException e) {
|
||||
throw CrashReports.report(e, "Could not analyze GLFW error codes");
|
||||
}
|
||||
}
|
||||
|
||||
public void onError(int errorCode, long descriptionPointer) {
|
||||
String description = GLFWErrorCallback.getDescription(descriptionPointer);
|
||||
|
||||
String errorCodeName;
|
||||
if (ERROR_CODES.hasConstant(errorCode)) {
|
||||
errorCodeName = ERROR_CODES.getName(errorCode);
|
||||
} else {
|
||||
errorCodeName = "<unknown " + Integer.toHexString(errorCode) + ">";
|
||||
}
|
||||
|
||||
throw CrashReports.report(null, "GLFW error detected: " + errorCodeName + " %s", description);
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,6 @@ import static org.lwjgl.system.MemoryUtil.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWImage;
|
||||
import org.lwjgl.opengl.GL;
|
||||
|
||||
@ -56,7 +55,6 @@ class LWJGLInitializer {
|
||||
setupWindowCallbacks();
|
||||
|
||||
glfwShowWindow(GraphicsBackend.getWindowHandle());
|
||||
GraphicsBackend.onFrameResized(GraphicsBackend.getWindowHandle(), 800, 600);
|
||||
}
|
||||
|
||||
private static void checkEnvironment() {
|
||||
@ -64,12 +62,8 @@ class LWJGLInitializer {
|
||||
}
|
||||
|
||||
private static void initializeGLFW() {
|
||||
GLFWErrorCallback.create(new GLFWErrorHandler()::onError).set();
|
||||
|
||||
if (!glfwInit()) {
|
||||
throw CrashReports.report(null, "GLFW could not be initialized: glfwInit() has failed");
|
||||
}
|
||||
|
||||
// TODO Do GLFW error handling: check glfwInit, setup error callback
|
||||
glfwInit();
|
||||
GraphicsBackend.setGLFWInitialized(true);
|
||||
}
|
||||
|
||||
@ -77,13 +71,17 @@ class LWJGLInitializer {
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
|
||||
|
||||
String windowTitle = Progressia.getName() + " " + Progressia.getFullerVersion();
|
||||
long handle = glfwCreateWindow(800, 600, windowTitle, NULL, NULL);
|
||||
long handle = glfwCreateWindow(
|
||||
800,
|
||||
600,
|
||||
Progressia.getName() + " " + Progressia.getFullerVersion(),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (handle == 0) {
|
||||
throw CrashReports.report(null, "Could not create game window");
|
||||
}
|
||||
// TODO Check that handle != NULL
|
||||
|
||||
GraphicsBackend.setWindowHandle(handle);
|
||||
|
||||
@ -97,8 +95,8 @@ class LWJGLInitializer {
|
||||
}
|
||||
|
||||
private static void createWindowIcons() {
|
||||
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) {
|
||||
// Wayland does not support changing window icons
|
||||
if (glfwGetVersionString().toLowerCase().contains("wayland")) {
|
||||
// glfwSetWindowIcon is not supported on Wayland
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
package ru.windcorp.progressia.client.graphics.gui;
|
||||
|
||||
import glm.mat._4.Mat4;
|
||||
import glm.vec._3.Vec3;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
|
||||
public class Background extends GUILayer {
|
||||
|
||||
protected Texture backgroundTexture;
|
||||
|
||||
public Background(String name, Layout layout, Texture inTexture) {
|
||||
super(name, layout);
|
||||
|
||||
backgroundTexture = inTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assemble(RenderTarget target) {
|
||||
getRoot().setBounds(0, 0, getWidth(), getHeight());
|
||||
getRoot().invalidate();
|
||||
target.pushTransform(new Mat4(1).translate(new Vec3(0,0,500)));
|
||||
target.drawTexture(0, 0, getWidth(), getHeight(), backgroundTexture);
|
||||
target.popTransform();
|
||||
getRoot().assemble(target);
|
||||
}
|
||||
|
||||
}
|
@ -18,9 +18,15 @@
|
||||
|
||||
package ru.windcorp.progressia.client.graphics.gui;
|
||||
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
|
||||
/** Class for a traditional button that gets clicked to activate
|
||||
*
|
||||
* @author opfromthestart
|
||||
*/
|
||||
public class Button extends BasicButton {
|
||||
|
||||
public Button(String name, String label, Font labelFont) {
|
||||
@ -37,26 +43,43 @@ public class Button extends BasicButton {
|
||||
|
||||
@Override
|
||||
protected void assembleSelf(RenderTarget target) {
|
||||
String state;
|
||||
if (!isEnabled()) {
|
||||
state = "Disabled";
|
||||
} else if (isPressed()) {
|
||||
state = "Pressed";
|
||||
} else if (isHovered()) {
|
||||
state = "Hovered";
|
||||
} else if (isFocused()) {
|
||||
state = "Focused";
|
||||
} else {
|
||||
state = "Inactive";
|
||||
}
|
||||
|
||||
// Border
|
||||
target.fill(getX(), getY(), getWidth(), getHeight(), ColorScheme.get("Core:ButtonBorder" + state));
|
||||
|
||||
Vec4 borderColor;
|
||||
if (isPressed() || isHovered() || isFocused()) {
|
||||
borderColor = Colors.BLUE;
|
||||
} else {
|
||||
borderColor = Colors.LIGHT_GRAY;
|
||||
}
|
||||
target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
|
||||
|
||||
// Inside area
|
||||
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, ColorScheme.get("Core:ButtonFill" + state));
|
||||
|
||||
if (!isPressed()) {
|
||||
Vec4 backgroundColor;
|
||||
if (isHovered() && isEnabled()) {
|
||||
backgroundColor = Colors.HOVER_BLUE;
|
||||
} else {
|
||||
backgroundColor = Colors.WHITE;
|
||||
}
|
||||
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
|
||||
}
|
||||
|
||||
// Change label font color
|
||||
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:ButtonText" + state)));
|
||||
|
||||
if (isPressed()) {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
|
||||
} else {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postAssembleSelf(RenderTarget target) {
|
||||
// Apply disable tint
|
||||
|
||||
if (!isEnabled()) {
|
||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
package ru.windcorp.progressia.client.graphics.gui;
|
||||
|
||||
import glm.vec._2.i.Vec2i;
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||
@ -41,28 +43,34 @@ public class Checkbox extends BasicButton {
|
||||
int x = getX();
|
||||
int y = getY() + (getHeight() - size) / 2;
|
||||
|
||||
String state;
|
||||
if (!Checkbox.this.isEnabled()) {
|
||||
state = "Disabled";
|
||||
} else if (Checkbox.this.isPressed()) {
|
||||
state = "Pressed";
|
||||
} else if (Checkbox.this.isHovered()) {
|
||||
state = "Hovered";
|
||||
} else if (Checkbox.this.isFocused()) {
|
||||
state = "Focused";
|
||||
} else {
|
||||
state = "Inactive";
|
||||
}
|
||||
|
||||
// Border
|
||||
target.fill(x, y, size, size, ColorScheme.get("Core:CheckboxBorder" + state));
|
||||
|
||||
Vec4 borderColor;
|
||||
if (Checkbox.this.isPressed() || Checkbox.this.isHovered() || Checkbox.this.isFocused()) {
|
||||
borderColor = Colors.BLUE;
|
||||
} else {
|
||||
borderColor = Colors.LIGHT_GRAY;
|
||||
}
|
||||
target.fill(x, y, size, size, borderColor);
|
||||
|
||||
// Inside area
|
||||
target.fill(x + 2, y + 2, size - 4, size - 4, ColorScheme.get("Core:CheckboxFill" + state));
|
||||
|
||||
if (Checkbox.this.isPressed()) {
|
||||
// Do nothing
|
||||
} else {
|
||||
Vec4 backgroundColor;
|
||||
if (Checkbox.this.isHovered() && Checkbox.this.isEnabled()) {
|
||||
backgroundColor = Colors.HOVER_BLUE;
|
||||
} else {
|
||||
backgroundColor = Colors.WHITE;
|
||||
}
|
||||
target.fill(x + 2, y + 2, size - 4, size - 4, backgroundColor);
|
||||
}
|
||||
|
||||
// "Tick"
|
||||
|
||||
if (Checkbox.this.isChecked()) {
|
||||
target.fill(x + 4, y + 4, size - 8, size - 8, ColorScheme.get("Core:CheckboxCheck" + state));
|
||||
target.fill(x + 4, y + 4, size - 8, size - 8, Colors.BLUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,21 +128,22 @@ public class Checkbox extends BasicButton {
|
||||
|
||||
@Override
|
||||
protected void assembleSelf(RenderTarget target) {
|
||||
String state;
|
||||
if (!Checkbox.this.isEnabled()) {
|
||||
state = "Disabled";
|
||||
} else if (Checkbox.this.isPressed()) {
|
||||
state = "Pressed";
|
||||
} else if (Checkbox.this.isHovered()) {
|
||||
state = "Hovered";
|
||||
} else if (Checkbox.this.isFocused()) {
|
||||
state = "Focused";
|
||||
} else {
|
||||
state = "Inactive";
|
||||
}
|
||||
|
||||
// Change label font color
|
||||
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:CheckboxText" + state)));
|
||||
|
||||
if (isPressed()) {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
||||
} else {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postAssembleSelf(RenderTarget target) {
|
||||
// Apply disable tint
|
||||
|
||||
if (!isEnabled()) {
|
||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2022 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.client.graphics.gui;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.jputil.SyntaxException;
|
||||
import ru.windcorp.jputil.chars.StringUtil;
|
||||
import ru.windcorp.progressia.common.resource.Resource;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.util.namespaces.IllegalIdException;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
|
||||
|
||||
public class ColorScheme {
|
||||
|
||||
private static Map<String, Vec4> defaultScheme;
|
||||
|
||||
public static Vec4 get(String key) {
|
||||
Vec4 color = defaultScheme.get(key);
|
||||
if (color == null) {
|
||||
throw CrashReports.report(null, "ColorScheme does not contain color %s", key);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public static void load(Resource resource) {
|
||||
Map<String, Vec4> tmpMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
for (String fullLine : StringUtil.split(resource.readAsString(), '\n')) {
|
||||
String line = fullLine.trim();
|
||||
if (line.isEmpty() || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] parts = StringUtil.split(line, '=', 2);
|
||||
if (parts[1] == null) {
|
||||
throw new SyntaxException("Could not parse \"" + line + "\": '=' not found");
|
||||
}
|
||||
|
||||
String key = parts[0].trim();
|
||||
checkKeyName(key);
|
||||
if (tmpMap.containsKey(key)) {
|
||||
throw new SyntaxException("Duplicate key " + key);
|
||||
}
|
||||
|
||||
String value = parts[1].trim();
|
||||
Vec4 color;
|
||||
|
||||
if (value.startsWith("#")) {
|
||||
color = parseValueAsHex(value);
|
||||
} else if (value.startsWith("$")) {
|
||||
color = parseValueAsReference(value, tmpMap);
|
||||
} else {
|
||||
throw new SyntaxException("Unknown value format \"" + value + "\"");
|
||||
}
|
||||
|
||||
tmpMap.put(key, color);
|
||||
}
|
||||
} catch (SyntaxException e) {
|
||||
throw CrashReports.report(e, "Could not load ColorScheme from %s", resource);
|
||||
}
|
||||
|
||||
defaultScheme = ImmutableMap.copyOf(tmpMap);
|
||||
}
|
||||
|
||||
private static void checkKeyName(String key) throws SyntaxException {
|
||||
try {
|
||||
NamespacedUtil.checkId(key);
|
||||
} catch (IllegalIdException e) {
|
||||
throw new SyntaxException("Illegal key name \"" + key + "\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseHex(String from, int start, int length) {
|
||||
return Integer.parseInt(from.substring(start, start + length), 0x10);
|
||||
}
|
||||
|
||||
private static Vec4 parseValueAsHex(String value) throws SyntaxException {
|
||||
int a = 0xFF;
|
||||
int r, g, b;
|
||||
|
||||
switch (value.length() - 1) {
|
||||
case 3:
|
||||
// #RGB
|
||||
r = parseHex(value, 1, 1) * 0x11;
|
||||
g = parseHex(value, 2, 1) * 0x11;
|
||||
b = parseHex(value, 3, 1) * 0x11;
|
||||
break;
|
||||
case 4:
|
||||
// #ARGB
|
||||
a = parseHex(value, 1, 1) * 0x11;
|
||||
r = parseHex(value, 2, 1) * 0x11;
|
||||
g = parseHex(value, 3, 1) * 0x11;
|
||||
b = parseHex(value, 4, 1) * 0x11;
|
||||
break;
|
||||
case 6:
|
||||
// #RRGGBB
|
||||
r = parseHex(value, 1, 2);
|
||||
g = parseHex(value, 3, 2);
|
||||
b = parseHex(value, 5, 2);
|
||||
break;
|
||||
case 8:
|
||||
// #AARRGGBB
|
||||
a = parseHex(value, 1, 2);
|
||||
r = parseHex(value, 3, 2);
|
||||
g = parseHex(value, 5, 2);
|
||||
b = parseHex(value, 7, 2);
|
||||
break;
|
||||
default:
|
||||
throw new SyntaxException("Could not parse hex color \"" + value + "\": expecting #RGB, #ARGB, #RRGGBB or #AARRGGBB");
|
||||
}
|
||||
|
||||
return new Vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||
}
|
||||
|
||||
private static Vec4 parseValueAsReference(String value, Map<String, Vec4> map) throws SyntaxException {
|
||||
String otherKey = value.substring(1);
|
||||
checkKeyName(otherKey);
|
||||
if (!map.containsKey(otherKey)) {
|
||||
throw new SyntaxException("Key $" + otherKey + " not found");
|
||||
}
|
||||
return map.get(otherKey);
|
||||
}
|
||||
|
||||
}
|
@ -20,6 +20,7 @@ package ru.windcorp.progressia.client.graphics.gui;
|
||||
import java.util.Objects;
|
||||
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
|
||||
public class Panel extends Group {
|
||||
@ -35,7 +36,7 @@ public class Panel extends Group {
|
||||
}
|
||||
|
||||
public Panel(String name, Layout layout) {
|
||||
this(name, layout, ColorScheme.get("Core:Background"), ColorScheme.get("Core:Border"));
|
||||
this(name, layout, Colors.WHITE, Colors.LIGHT_GRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import glm.vec._2.i.Vec2i;
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||
@ -51,28 +52,34 @@ public class RadioButton extends BasicButton {
|
||||
int x = getX();
|
||||
int y = getY() + (getHeight() - size) / 2;
|
||||
|
||||
String state;
|
||||
if (!RadioButton.this.isEnabled()) {
|
||||
state = "Disabled";
|
||||
} else if (RadioButton.this.isPressed()) {
|
||||
state = "Pressed";
|
||||
} else if (RadioButton.this.isHovered()) {
|
||||
state = "Hovered";
|
||||
} else if (RadioButton.this.isFocused()) {
|
||||
state = "Focused";
|
||||
} else {
|
||||
state = "Inactive";
|
||||
}
|
||||
|
||||
// Border
|
||||
cross(target, x, y, size, ColorScheme.get("Core:RadioButtonBorder" + state));
|
||||
|
||||
Vec4 borderColor;
|
||||
if (RadioButton.this.isPressed() || RadioButton.this.isHovered() || RadioButton.this.isFocused()) {
|
||||
borderColor = Colors.BLUE;
|
||||
} else {
|
||||
borderColor = Colors.LIGHT_GRAY;
|
||||
}
|
||||
cross(target, x, y, size, borderColor);
|
||||
|
||||
// Inside area
|
||||
cross(target, x + 2, y + 2, size - 4, ColorScheme.get("Core:RadioButtonFill" + state));
|
||||
|
||||
if (RadioButton.this.isPressed()) {
|
||||
// Do nothing
|
||||
} else {
|
||||
Vec4 backgroundColor;
|
||||
if (RadioButton.this.isHovered() && RadioButton.this.isEnabled()) {
|
||||
backgroundColor = Colors.HOVER_BLUE;
|
||||
} else {
|
||||
backgroundColor = Colors.WHITE;
|
||||
}
|
||||
cross(target, x + 2, y + 2, size - 4, backgroundColor);
|
||||
}
|
||||
|
||||
// "Tick"
|
||||
|
||||
if (RadioButton.this.isChecked()) {
|
||||
cross(target, x + 4, y + 4, size - 8, ColorScheme.get("Core:RadioButtonCheck" + state));
|
||||
cross(target, x + 4, y + 4, size - 8, Colors.BLUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,8 +146,8 @@ public class RadioButton extends BasicButton {
|
||||
group.selectNext();
|
||||
removeAction(group.listener);
|
||||
group.buttons.remove(this);
|
||||
// Clear reference if this was the only button in the group
|
||||
group.getSelected();
|
||||
group.getSelected(); // Clear reference if this was the only button
|
||||
// in the group
|
||||
}
|
||||
|
||||
this.group = group;
|
||||
@ -176,21 +183,22 @@ public class RadioButton extends BasicButton {
|
||||
|
||||
@Override
|
||||
protected void assembleSelf(RenderTarget target) {
|
||||
String state;
|
||||
if (!RadioButton.this.isEnabled()) {
|
||||
state = "Disabled";
|
||||
} else if (RadioButton.this.isPressed()) {
|
||||
state = "Pressed";
|
||||
} else if (RadioButton.this.isHovered()) {
|
||||
state = "Hovered";
|
||||
} else if (RadioButton.this.isFocused()) {
|
||||
state = "Focused";
|
||||
} else {
|
||||
state = "Inactive";
|
||||
}
|
||||
|
||||
// Change label font color
|
||||
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:RadioButtonText" + state)));
|
||||
|
||||
if (isPressed()) {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
||||
} else {
|
||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postAssembleSelf(RenderTarget target) {
|
||||
// Apply disable tint
|
||||
|
||||
if (!isEnabled()) {
|
||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
package ru.windcorp.progressia.client.graphics.gui;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
|
||||
public class TextureComponent extends Component {
|
||||
|
||||
private final Texture texture;
|
||||
|
||||
public TextureComponent(String name, Texture texture2) {
|
||||
super(name);
|
||||
|
||||
texture = texture2;
|
||||
setPreferredSize(texture.getSprite().getWidth(),texture.getSprite().getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleSelf(RenderTarget target)
|
||||
{
|
||||
target.drawTexture(getX(), getY(), getWidth(), getHeight(), texture);
|
||||
}
|
||||
|
||||
}
|
@ -27,8 +27,8 @@ import ru.windcorp.progressia.client.graphics.gui.Layout;
|
||||
|
||||
public class LayoutAlign implements Layout {
|
||||
|
||||
private final int margin;
|
||||
private double alignX, alignY;
|
||||
protected final int margin;
|
||||
protected double alignX, alignY;
|
||||
|
||||
public LayoutAlign(double alignX, double alignY, int margin) {
|
||||
this.alignX = alignX;
|
||||
@ -72,7 +72,7 @@ public class LayoutAlign implements Layout {
|
||||
Vec2i result = new Vec2i(0, 0);
|
||||
|
||||
c.getChildren().stream()
|
||||
.map(child -> child.getPreferredSize())
|
||||
.map(Component::getPreferredSize)
|
||||
.forEach(size -> {
|
||||
result.x = max(size.x, result.x);
|
||||
result.y = max(size.y, result.y);
|
||||
|
@ -0,0 +1,56 @@
|
||||
package ru.windcorp.progressia.client.graphics.gui.layout;
|
||||
|
||||
import glm.vec._2.i.Vec2i;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Layout;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
public class LayoutEdges implements Layout {
|
||||
|
||||
private final int margin;
|
||||
|
||||
public LayoutEdges(int margin) {
|
||||
this.margin = margin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layout(Component c) {
|
||||
for (int i=0;i<2;i++)
|
||||
{
|
||||
Component child = c.getChild(i);
|
||||
|
||||
Vec2i size = child.getPreferredSize();
|
||||
|
||||
int cWidth = c.getWidth() - 2 * margin;
|
||||
int cHeight = c.getHeight() - 2 * margin;
|
||||
|
||||
size.x = min(size.x, cWidth);
|
||||
size.y = min(size.y, cHeight);
|
||||
|
||||
if (i==0) {
|
||||
child.setBounds(
|
||||
c.getX() + margin,
|
||||
c.getY(),
|
||||
size
|
||||
);
|
||||
} else {
|
||||
child.setBounds(
|
||||
1920 - size.x - margin,
|
||||
c.getY(),
|
||||
size
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i calculatePreferredSize(Component c) {
|
||||
Vec2i result = new Vec2i(1920,0);
|
||||
c.getChildren().stream()
|
||||
.map(Component::getPreferredSize)
|
||||
.forEach(size -> result.y = max(Math.abs(size.y), result.y));
|
||||
return result;
|
||||
}
|
||||
}
|
@ -20,9 +20,9 @@ package ru.windcorp.progressia.client.graphics.gui.menu;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import glm.vec._2.i.Vec2i;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.GUI;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||
@ -50,7 +50,7 @@ public class MenuLayer extends GUILayer {
|
||||
|
||||
setCursorPolicy(CursorPolicy.REQUIRE);
|
||||
|
||||
this.background = new Panel(name + ".Background", new LayoutAlign(10), ColorScheme.get("Core:MenuLayerTint"), null);
|
||||
this.background = new Panel(name + ".Background", new LayoutAlign(10), Colors.toVector(0x66000000), null);
|
||||
this.content = content;
|
||||
|
||||
background.addChild(content);
|
||||
@ -76,12 +76,12 @@ public class MenuLayer extends GUILayer {
|
||||
protected void addTitle() {
|
||||
String translationKey = "Layer" + getName() + ".Title";
|
||||
MutableString titleText = new MutableStringLocalized(translationKey);
|
||||
Font titleFont = new Font().deriveBold().withColor(ColorScheme.get("Core:Text")).withAlign(0.5f);
|
||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
||||
|
||||
Label label = new Label(getName() + ".Title", titleFont, titleText);
|
||||
getContent().addChild(label);
|
||||
|
||||
Panel panel = new Panel(getName() + ".Title.Underscore", null, ColorScheme.get("Core:Accent"), null);
|
||||
Panel panel = new Panel(getName() + ".Title.Underscore", null, Colors.BLUE, null);
|
||||
panel.setLayout(new LayoutFill() {
|
||||
@Override
|
||||
public Vec2i calculatePreferredSize(Component c) {
|
||||
|
@ -43,10 +43,8 @@ public class Region {
|
||||
|
||||
private static final boolean RESET_CORRUPTED = true;
|
||||
|
||||
public int loadedChunks;
|
||||
|
||||
private AtomicBoolean isUsing = new AtomicBoolean(false);
|
||||
private AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
private final AtomicBoolean isUsing = new AtomicBoolean(false);
|
||||
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
|
||||
private final RegionFile file;
|
||||
|
||||
@ -60,6 +58,7 @@ public class Region {
|
||||
} catch (IOException e) {
|
||||
|
||||
RegionWorldContainer.LOG.debug("Uh the file broke");
|
||||
RegionWorldContainer.LOG.debug(e.getLocalizedMessage());
|
||||
if (RESET_CORRUPTED) {
|
||||
this.file.makeHeader(regionCoords);
|
||||
}
|
||||
@ -132,7 +131,7 @@ public class Region {
|
||||
DecodingException {
|
||||
isUsing.set(true);
|
||||
|
||||
int dataOffset = 0;
|
||||
int dataOffset;
|
||||
Vec3i pos = RegionWorldContainer.getInRegionCoords(chunkPos);
|
||||
|
||||
if (hasOffset(pos)) {
|
||||
|
@ -26,9 +26,9 @@ public class RegionFile {
|
||||
private static final int ID_HEADER_SIZE = 16;
|
||||
private static final byte[] HEADER_ID = {'P','R','O','G'};
|
||||
|
||||
final byte endBytes[] = new byte[SECTOR_SIZE];
|
||||
final byte[] endBytes = new byte[SECTOR_SIZE];
|
||||
|
||||
public static enum SectorType {
|
||||
public enum SectorType {
|
||||
Ending(0), // Just an empty block
|
||||
Data(1), // has a byte counting up in position 1, and then
|
||||
PartitionLink(2),
|
||||
@ -54,7 +54,7 @@ public class RegionFile {
|
||||
|
||||
public void confirmHeaderHealth(ChunkMap<Integer> offsets, Vec3i regionCoords) throws IOException {
|
||||
|
||||
Set<Integer> used = new HashSet<Integer>();
|
||||
Set<Integer> used = new HashSet<>();
|
||||
int maxUsed = 0;
|
||||
final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER;
|
||||
|
||||
@ -63,9 +63,10 @@ public class RegionFile {
|
||||
}
|
||||
|
||||
|
||||
char prog;
|
||||
byte prog;
|
||||
file.seek(0);
|
||||
for (int i=0;i<4;i++) {
|
||||
prog = file.readChar();
|
||||
prog = file.readByte();
|
||||
if (prog != HEADER_ID[i])
|
||||
{
|
||||
throw new IOException("File is not a .progressia_chunk file");
|
||||
@ -109,7 +110,7 @@ public class RegionFile {
|
||||
throw new IOException("A sector is used twice");
|
||||
}
|
||||
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * offset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * offset);
|
||||
byte type = file.readByte();
|
||||
|
||||
if (type == SectorType.Data.data) {
|
||||
@ -131,25 +132,26 @@ public class RegionFile {
|
||||
}
|
||||
|
||||
public void makeHeader(Vec3i regionCoords) throws IOException {
|
||||
file.seek(0);
|
||||
for (int i = 0; i < HEADER_SIZE; i++) {
|
||||
file.write(0);
|
||||
}
|
||||
file.seek(0);
|
||||
file.write(HEADER_ID);
|
||||
file.writeInt(regionCoords.x);
|
||||
file.writeInt(regionCoords.y);
|
||||
file.writeInt(regionCoords.z);
|
||||
for (int i = 0; i < HEADER_SIZE; i++) {
|
||||
file.write(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBuffer(byte[] buffer, int dataOffset, Vec3i pos) throws IOException {
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||
int loc = 0;
|
||||
byte tempBuffer[] = new byte[SECTOR_SIZE];
|
||||
byte[] tempBuffer = new byte[SECTOR_SIZE];
|
||||
byte counter = 0;
|
||||
boolean isDone = false;
|
||||
while (!isDone) {
|
||||
if (file.length() > HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1)) {
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1));
|
||||
if (file.length() > HEADER_SIZE + (long) SECTOR_SIZE * (dataOffset + 1)) {
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * (dataOffset + 1));
|
||||
byte header = file.readByte();
|
||||
if (header == SectorType.Data.data) {
|
||||
byte fileCounter = file.readByte();
|
||||
@ -157,7 +159,7 @@ public class RegionFile {
|
||||
// partition place
|
||||
{
|
||||
int newOffset = allocateEmptySector();
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||
file.write(2);
|
||||
file.writeInt(newOffset);
|
||||
dataOffset = newOffset;
|
||||
@ -179,7 +181,7 @@ public class RegionFile {
|
||||
if (file.getFilePointer() < 256)
|
||||
LogManager.getLogger("Region")
|
||||
.debug("at {}, ({},{},{}), {}", file.getFilePointer(), pos.x, pos.y, pos.z, dataOffset);
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||
dataOffset++;
|
||||
file.write(tempBuffer);
|
||||
}
|
||||
@ -197,7 +199,7 @@ public class RegionFile {
|
||||
file.seek(definitionOffset);
|
||||
file.writeInt(dataOffset + 1);
|
||||
|
||||
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
|
||||
file.setLength(HEADER_SIZE + (long) dataOffset * SECTOR_SIZE);
|
||||
return dataOffset;
|
||||
}
|
||||
|
||||
@ -206,17 +208,17 @@ public class RegionFile {
|
||||
|
||||
int dataOffset = (int) Math.ceil((double) (outputLen - HEADER_SIZE) / SECTOR_SIZE);
|
||||
|
||||
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
|
||||
file.setLength(HEADER_SIZE + (long) dataOffset * SECTOR_SIZE);
|
||||
|
||||
return dataOffset;
|
||||
}
|
||||
|
||||
public byte[] readBuffer(int dataOffset) throws IOException {
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||
|
||||
int bufferPos = 0;
|
||||
byte buffer[] = new byte[SECTOR_SIZE * 16];
|
||||
byte tempBuffer[] = new byte[SECTOR_SIZE];
|
||||
byte[] buffer = new byte[SECTOR_SIZE * 16];
|
||||
byte[] tempBuffer = new byte[SECTOR_SIZE];
|
||||
|
||||
boolean reachedEnd = false;
|
||||
byte counter = 0;
|
||||
@ -229,31 +231,24 @@ public class RegionFile {
|
||||
if (tempBuffer[0] == SectorType.Data.data) {
|
||||
if (tempBuffer[1] != counter) {
|
||||
throw new IOException(
|
||||
"Sectors were read out of order\nExpected chunk number " + Byte.toString(counter)
|
||||
+ " but encountered number " + Byte.toString(tempBuffer[1])
|
||||
"Sectors were read out of order\nExpected chunk number " + counter
|
||||
+ " but encountered number " + tempBuffer[1]
|
||||
);
|
||||
}
|
||||
counter++;
|
||||
if (buffer.length - bufferPos < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1) {
|
||||
byte newBuffer[] = new byte[buffer.length + SECTOR_SIZE * 16];
|
||||
for (int i = 0; i < buffer.length; i++) // TODO dedicated
|
||||
// copy, java-y at
|
||||
// least
|
||||
{
|
||||
newBuffer[i] = buffer[i];
|
||||
}
|
||||
byte[] newBuffer = new byte[buffer.length + SECTOR_SIZE * 16];
|
||||
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
|
||||
buffer = newBuffer;
|
||||
}
|
||||
for (int i = 0; i < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1; i++) {
|
||||
buffer[bufferPos + i] = tempBuffer[i + 2];
|
||||
}
|
||||
System.arraycopy(tempBuffer, 2, buffer, bufferPos, SECTOR_SIZE - SECTOR_HEADER_SIZE - 1);
|
||||
bufferPos += SECTOR_SIZE - SECTOR_HEADER_SIZE - 1;
|
||||
} else if (tempBuffer[0] == SectorType.Ending.data) {
|
||||
reachedEnd = true;
|
||||
} else if (tempBuffer[0] == SectorType.PartitionLink.data) {
|
||||
ByteBuffer intBuffer = ByteBuffer.wrap(tempBuffer);
|
||||
int newOffset = intBuffer.getInt(1);
|
||||
file.seek(HEADER_SIZE + SECTOR_SIZE * newOffset);
|
||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * newOffset);
|
||||
} else {
|
||||
throw new IOException("Invalid sector ID.");
|
||||
}
|
||||
|
108
src/main/java/ru/windcorp/progressia/test/CubeComponent.java
Normal file
108
src/main/java/ru/windcorp/progressia/test/CubeComponent.java
Normal file
@ -0,0 +1,108 @@
|
||||
package ru.windcorp.progressia.test;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import glm.mat._4.Mat4;
|
||||
import glm.vec._3.Vec3;
|
||||
import glm.vec._4.Vec4;
|
||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||
|
||||
public class CubeComponent extends Component {
|
||||
|
||||
private final Mat4[] transforms;
|
||||
private final Vec4[] normals;
|
||||
private final long startTime;
|
||||
|
||||
private final double r3 = Math.sqrt(3+.01);
|
||||
|
||||
private final int size;
|
||||
|
||||
public CubeComponent(String name, int size) {
|
||||
super(name);
|
||||
this.size = size;
|
||||
transforms = new Mat4[6];
|
||||
normals = new Vec4[6];
|
||||
setPreferredSize((int) Math.ceil(r3*size),(int) Math.ceil(r3*size));
|
||||
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||
executor.scheduleAtFixedRate(this::requestReassembly, 1, 60, TimeUnit.MILLISECONDS);
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Notes to me
|
||||
// z axis is through the screen
|
||||
// y is horizontal spin
|
||||
// x is vertical spin
|
||||
|
||||
|
||||
private void computeTransforms()
|
||||
{
|
||||
//Creates all of the sides
|
||||
transforms[0] = new Mat4(1);
|
||||
transforms[1] = new Mat4(1);
|
||||
transforms[2] = new Mat4(1);
|
||||
transforms[3] = new Mat4(1);
|
||||
transforms[4] = new Mat4(1);
|
||||
transforms[5] = new Mat4(1);
|
||||
|
||||
//Gets time since creation(for rotation amount)
|
||||
long time = System.currentTimeMillis()-startTime;
|
||||
|
||||
//Initializes the way each face is facing
|
||||
normals[0] = new Vec4(0,0,-1,0);
|
||||
normals[1] = new Vec4(0,1,0,0);
|
||||
normals[2] = new Vec4(1,0,0,0);
|
||||
normals[3] = new Vec4(0,0,1,0);
|
||||
normals[4] = new Vec4(0,-1,0,0);
|
||||
normals[5] = new Vec4(-1,0,0,0);
|
||||
|
||||
for (int i=0;i<6;i++)
|
||||
{
|
||||
//Rotates given side with the time one first, then ot get it on its off axis, then gets the image of each axis under the given rotation
|
||||
//The rotate functions do change the transforms, but the multiplication does not
|
||||
normals[i] = transforms[i].rotate((float) (time%(6000*6.28) )/ 6000, new Vec3(0,1,0)).rotate((float) 24, new Vec3(1,.5,0)).mul_(normals[i]);
|
||||
}
|
||||
double pi2 = Math.PI / 2;
|
||||
|
||||
//Move and rotate the sides from the middle of the cube to the appropriate edges
|
||||
transforms[0].translate(new Vec3(-size/2f,-size/2f,size/2f));
|
||||
transforms[1].translate(new Vec3(-size/2f,-size/2f,-size/2f)).rotate((float) pi2, new Vec3(1,0,0));
|
||||
transforms[2].translate(new Vec3(-size/2f,-size/2f,size/2f)).rotate((float) pi2, new Vec3(0,1,0));
|
||||
transforms[3].translate(new Vec3(-size/2f,-size/2f,-size/2f));
|
||||
transforms[4].translate(new Vec3(-size/2f,size/2f,-size/2f)).rotate((float) pi2, new Vec3(1,0,0));
|
||||
transforms[5].translate(new Vec3(size/2f,-size/2f,size/2f)).rotate((float) pi2, new Vec3(0,1,0));
|
||||
|
||||
for (int i=0;i<6;i++) // I have no clue why this is necessary, without it the sides of the cube mess up; may need to be changed if the title screen changes position.
|
||||
{
|
||||
transforms[i] = transforms[i].translate(new Vec3(0,0,17.5-3*(i<2 ? 1 : 0)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleSelf(RenderTarget target)
|
||||
{
|
||||
computeTransforms();
|
||||
|
||||
setPosition(750,780);
|
||||
|
||||
target.pushTransform(new Mat4(1).translate(new Vec3(getX()+size*r3/2,getY()-size*r3/2,0))); //-size*r3/2
|
||||
|
||||
for (int b=0; b<6;b++)
|
||||
{
|
||||
target.pushTransform(transforms[b]);
|
||||
|
||||
float dot = normals[b].dot(new Vec4(-1,0,0,0)); //Gets the "amount" the given side is pointing in the -x direction
|
||||
|
||||
Vec4 color = new Vec4(.4+.3*dot, .4+.3*dot, .6+.4*dot,1.0); //More aligned means brighter color
|
||||
|
||||
target.fill(0,0, size, size, color);
|
||||
|
||||
target.popTransform();
|
||||
}
|
||||
|
||||
target.popTransform();
|
||||
}
|
||||
}
|
@ -22,7 +22,6 @@ import ru.windcorp.progressia.Progressia;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.font.Typeface;
|
||||
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Group;
|
||||
@ -32,13 +31,15 @@ import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||
|
||||
public class LayerAbout extends GUILayer {
|
||||
|
||||
public static String version = "pre-alpha 3";
|
||||
|
||||
public LayerAbout() {
|
||||
super("LayerAbout", new LayoutAlign(1, 1, 5));
|
||||
|
||||
Group group = new Group("ControlDisplays", new LayoutVertical(5));
|
||||
|
||||
Font font = new Font().withColor(Colors.WHITE).deriveOutlined().withAlign(Typeface.ALIGN_RIGHT);
|
||||
Font aboutFont = font.withColor(ColorScheme.get("Core:Accent")).deriveBold();
|
||||
Font aboutFont = font.withColor(0xFF37A3E6).deriveBold();
|
||||
|
||||
group.addChild(
|
||||
new Label(
|
||||
|
@ -20,11 +20,11 @@ package ru.windcorp.progressia.test;
|
||||
import java.util.Collection;
|
||||
|
||||
import ru.windcorp.progressia.client.ClientState;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.GUI;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Checkbox;
|
||||
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||
import ru.windcorp.progressia.client.graphics.gui.RadioButton;
|
||||
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
|
||||
@ -65,7 +65,7 @@ public class LayerButtonTest extends MenuLayer {
|
||||
|
||||
getContent().getChild(getContent().getChildren().size() - 1).setEnabled(false);
|
||||
|
||||
getContent().addChild(new Label("Hint", new Font().withColor(ColorScheme.get("Core:Border")), "This is a MenuLayer"));
|
||||
getContent().addChild(new Label("Hint", new Font().withColor(Colors.LIGHT_GRAY), "This is a MenuLayer"));
|
||||
|
||||
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
|
||||
getCloseAction().run();
|
||||
|
53
src/main/java/ru/windcorp/progressia/test/LayerOptions.java
Normal file
53
src/main/java/ru/windcorp/progressia/test/LayerOptions.java
Normal file
@ -0,0 +1,53 @@
|
||||
package ru.windcorp.progressia.test;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.GUI;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.gui.*;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
||||
import ru.windcorp.progressia.client.localization.Localizer;
|
||||
import ru.windcorp.progressia.client.localization.MutableString;
|
||||
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LayerOptions extends Background {
|
||||
public LayerOptions(String name) {
|
||||
super(name, new LayoutAlign(0, 1f, 15), SimpleTextures.get("title/background"));
|
||||
|
||||
Group content = new Group("Layer" + name + ".Group", new LayoutVertical(15));
|
||||
|
||||
Font font = new Font().withColor(Colors.BLUE).withAlign(0.5f);
|
||||
|
||||
MutableString languageText = new MutableStringLocalized("Layer" + name + ".Language");
|
||||
content.addChild(new Button(name + ".Language", new Label(name + ".Language", font, languageText)).addAction(this::toggleLanguage));
|
||||
|
||||
MutableString playText = new MutableStringLocalized("Layer" + name + ".Return");
|
||||
content.addChild(new Button(name + ".Return", new Label(name + ".Return", font, playText)).addAction(this::openTitle));
|
||||
|
||||
getRoot().addChild(content);
|
||||
}
|
||||
|
||||
private void openTitle(BasicButton basicButton) {
|
||||
GUI.removeLayer(this);
|
||||
GUI.addTopLayer(new LayerTitle("Title"));
|
||||
}
|
||||
|
||||
private void toggleLanguage(BasicButton basicButton)
|
||||
{
|
||||
String curLang = Localizer.getInstance().getLanguage();
|
||||
List<String> allLangs = Localizer.getInstance().getLanguages();
|
||||
int pos = allLangs.indexOf(curLang);
|
||||
pos++;
|
||||
if (pos >= allLangs.size())
|
||||
{
|
||||
Localizer.getInstance().setLanguage(allLangs.get(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
Localizer.getInstance().setLanguage(allLangs.get(pos));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
package ru.windcorp.progressia.test;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Panel;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill;
|
||||
import ru.windcorp.progressia.client.localization.MutableString;
|
||||
|
||||
public class LayerTestText extends GUILayer {
|
||||
@ -15,13 +13,11 @@ public class LayerTestText extends GUILayer {
|
||||
private final Consumer<LayerTestText> remover;
|
||||
|
||||
public LayerTestText(String name, MutableString value, Consumer<LayerTestText> remover) {
|
||||
super(name, new LayoutFill());
|
||||
super(name, new LayoutAlign(15));
|
||||
this.remover = remover;
|
||||
|
||||
Panel panel = new Panel(name + ".Background", new LayoutAlign(15), ColorScheme.get("Core:Background"), null);
|
||||
Font titleFont = new Font().deriveBold().withColor(ColorScheme.get("Core:Text")).withAlign(0.5f);
|
||||
panel.addChild(new Label(name + ".Text", titleFont, value));
|
||||
getRoot().addChild(panel);
|
||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
||||
getRoot().addChild(new Label(name + ".Text", titleFont, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,16 +1,20 @@
|
||||
package ru.windcorp.progressia.test;
|
||||
|
||||
import ru.windcorp.progressia.Progressia;
|
||||
import ru.windcorp.progressia.client.ClientState;
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.GUI;
|
||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Background;
|
||||
import ru.windcorp.progressia.client.graphics.gui.BasicButton;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Group;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||
import ru.windcorp.progressia.client.graphics.gui.TextureComponent;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutEdges;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
||||
import ru.windcorp.progressia.client.localization.MutableString;
|
||||
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
@ -24,34 +28,58 @@ import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public class LayerTitle extends GUILayer {
|
||||
public class LayerTitle extends Background {
|
||||
|
||||
private final BasicButton resetButton;
|
||||
|
||||
public LayerTitle(String name) {
|
||||
super(name, new LayoutAlign(0.5f, 0.7f, 15));
|
||||
super(name, new LayoutAlign(0, 1f, 15), SimpleTextures.get("title/background"));
|
||||
Group content = new Group("Layer" + name + ".Group", new LayoutVertical(15));
|
||||
Group info = new Group("Layer"+name+".InfoGroup", new LayoutEdges(30));
|
||||
Group buttonContent = new Group("Layer" + name + ".ButtonGroup", new LayoutColumn(15, 320));
|
||||
|
||||
MutableString title = new MutableStringLocalized("Layer" + name + ".Title");
|
||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
||||
content.addChild(new Label(name + ".Title", titleFont, title));
|
||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLUE).withAlign(0.5f);
|
||||
content.addChild(new TextureComponent(name + ".Title", SimpleTextures.get("title/progressia")));
|
||||
|
||||
info.addChild(new Label(
|
||||
"About",
|
||||
titleFont,
|
||||
new MutableStringLocalized("LayerAbout.Title")
|
||||
)
|
||||
);
|
||||
|
||||
info.addChild(
|
||||
new Label(
|
||||
"Version",
|
||||
titleFont,
|
||||
Progressia.getFullerVersion()
|
||||
)
|
||||
);
|
||||
content.addChild(info);
|
||||
|
||||
Font buttonFont = titleFont.deriveNotBold();
|
||||
MutableString playText = new MutableStringLocalized("Layer" + name + ".Play");
|
||||
content.addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
|
||||
buttonContent.addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
|
||||
|
||||
MutableString resetText = new MutableStringLocalized("Layer" + name + ".Reset");
|
||||
this.resetButton = new Button(name + ".Reset", new Label(name + ".Reset", buttonFont, resetText)).addAction(this::resetWorld);
|
||||
content.addChild(resetButton);
|
||||
buttonContent.addChild(resetButton);
|
||||
|
||||
updateResetButton();
|
||||
|
||||
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
|
||||
content.addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> {
|
||||
System.exit(0);
|
||||
}));
|
||||
MutableString settingsText = new MutableStringLocalized("Layer" + name + ".Options");
|
||||
buttonContent.addChild(new Button(name + ".Options", new Label(name + ".Options", buttonFont, settingsText)).addAction(this::openOptions));
|
||||
|
||||
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
|
||||
buttonContent.addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> System.exit(0)));
|
||||
|
||||
content.addChild(buttonContent);
|
||||
getRoot().addChild(content);
|
||||
buttonContent.setPreferredSize(500, 1000);
|
||||
|
||||
CubeComponent cube = new CubeComponent(name+".Cube",300);
|
||||
|
||||
getRoot().addChild(cube);
|
||||
}
|
||||
|
||||
private void updateResetButton() {
|
||||
@ -92,4 +120,9 @@ public class LayerTitle extends GUILayer {
|
||||
updateResetButton();
|
||||
}
|
||||
|
||||
private void openOptions(BasicButton basicButton) {
|
||||
GUI.removeLayer(this);
|
||||
GUI.addTopLayer(new LayerOptions("Options"));
|
||||
}
|
||||
|
||||
}
|
||||
|
33
src/main/java/ru/windcorp/progressia/test/LayoutColumn.java
Normal file
33
src/main/java/ru/windcorp/progressia/test/LayoutColumn.java
Normal file
@ -0,0 +1,33 @@
|
||||
package ru.windcorp.progressia.test;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||
|
||||
public class LayoutColumn extends LayoutVertical {
|
||||
|
||||
protected int maxWidth;
|
||||
private final int margin;
|
||||
|
||||
public LayoutColumn(int gap, int maxWidth)
|
||||
{
|
||||
super(gap);
|
||||
this.maxWidth = maxWidth;
|
||||
margin = gap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layout(Component c) {
|
||||
int x = c.getX() + margin,
|
||||
y = c.getY() + c.getHeight();
|
||||
|
||||
synchronized (c.getChildren()) {
|
||||
for (Component child : c.getChildren()) {
|
||||
|
||||
int height = child.getPreferredSize().y;
|
||||
y -= margin + height;
|
||||
child.setBounds(x, y, maxWidth, height);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
# Default color scheme for Progressia
|
||||
#
|
||||
# Line format:
|
||||
# KEY = VALUE
|
||||
# KEY must be a legal ID
|
||||
# VALUE may be one of the following:
|
||||
# #RGB
|
||||
# #ARGB
|
||||
# #RRGGBB
|
||||
# #AARRGGBB
|
||||
# $OTHER_KEY
|
||||
|
||||
Core:Background = #EFF0F1
|
||||
Core:Border = #CBCBD0
|
||||
Core:DisabledBackground = $Core:Background
|
||||
Core:DisabledBorder = #DEDFE1
|
||||
Core:Accent = #37A3E6
|
||||
Core:AccentLighter = #C3E4F7
|
||||
|
||||
Core:Text = #31363B
|
||||
|
||||
Core:ButtonBorderDisabled = $Core:DisabledBorder
|
||||
Core:ButtonBorderPressed = $Core:Accent
|
||||
Core:ButtonBorderHovered = $Core:Accent
|
||||
Core:ButtonBorderFocused = $Core:Accent
|
||||
Core:ButtonBorderInactive = $Core:Border
|
||||
Core:ButtonFillDisabled = $Core:DisabledBackground
|
||||
Core:ButtonFillPressed = $Core:Accent
|
||||
Core:ButtonFillHovered = $Core:AccentLighter
|
||||
Core:ButtonFillFocused = $Core:Background
|
||||
Core:ButtonFillInactive = $Core:Background
|
||||
Core:ButtonTextDisabled = $Core:DisabledBorder
|
||||
Core:ButtonTextPressed = $Core:Background
|
||||
Core:ButtonTextHovered = $Core:Text
|
||||
Core:ButtonTextFocused = $Core:Text
|
||||
Core:ButtonTextInactive = $Core:Text
|
||||
|
||||
Core:CheckboxBorderDisabled = $Core:DisabledBorder
|
||||
Core:CheckboxBorderPressed = $Core:Accent
|
||||
Core:CheckboxBorderHovered = $Core:Accent
|
||||
Core:CheckboxBorderFocused = $Core:Accent
|
||||
Core:CheckboxBorderInactive = $Core:Border
|
||||
Core:CheckboxFillDisabled = $Core:DisabledBackground
|
||||
Core:CheckboxFillPressed = $Core:Accent
|
||||
Core:CheckboxFillHovered = $Core:AccentLighter
|
||||
Core:CheckboxFillFocused = $Core:Background
|
||||
Core:CheckboxFillInactive = $Core:Background
|
||||
Core:CheckboxTextDisabled = $Core:DisabledBorder
|
||||
Core:CheckboxTextPressed = $Core:Accent
|
||||
Core:CheckboxTextHovered = $Core:Text
|
||||
Core:CheckboxTextFocused = $Core:Text
|
||||
Core:CheckboxTextInactive = $Core:Text
|
||||
Core:CheckboxCheckDisabled = $Core:DisabledBorder
|
||||
Core:CheckboxCheckPressed = $Core:Accent
|
||||
Core:CheckboxCheckHovered = $Core:Accent
|
||||
Core:CheckboxCheckFocused = $Core:Accent
|
||||
Core:CheckboxCheckInactive = $Core:Accent
|
||||
|
||||
Core:RadioButtonBorderDisabled = $Core:DisabledBorder
|
||||
Core:RadioButtonBorderPressed = $Core:Accent
|
||||
Core:RadioButtonBorderHovered = $Core:Accent
|
||||
Core:RadioButtonBorderFocused = $Core:Accent
|
||||
Core:RadioButtonBorderInactive = $Core:Border
|
||||
Core:RadioButtonFillDisabled = $Core:DisabledBackground
|
||||
Core:RadioButtonFillPressed = $Core:Accent
|
||||
Core:RadioButtonFillHovered = $Core:AccentLighter
|
||||
Core:RadioButtonFillFocused = $Core:Background
|
||||
Core:RadioButtonFillInactive = $Core:Background
|
||||
Core:RadioButtonTextDisabled = $Core:DisabledBorder
|
||||
Core:RadioButtonTextPressed = $Core:Accent
|
||||
Core:RadioButtonTextHovered = $Core:Text
|
||||
Core:RadioButtonTextFocused = $Core:Text
|
||||
Core:RadioButtonTextInactive = $Core:Text
|
||||
Core:RadioButtonCheckDisabled = $Core:DisabledBorder
|
||||
Core:RadioButtonCheckPressed = $Core:Accent
|
||||
Core:RadioButtonCheckHovered = $Core:Accent
|
||||
Core:RadioButtonCheckFocused = $Core:Accent
|
||||
Core:RadioButtonCheckInactive = $Core:Accent
|
||||
|
||||
Core:MenuLayerTint = #6000
|
@ -24,5 +24,8 @@ LayerTitle.Reset = Reset World
|
||||
LayerTitle.Options = Options
|
||||
LayerTitle.Quit = Quit
|
||||
|
||||
LayerOptions.Return = Back To Menu
|
||||
LayerOptions.Language = US English
|
||||
|
||||
LayerText.Load = Loading...
|
||||
LayerText.Save = Saving...
|
@ -24,5 +24,8 @@ LayerTitle.Reset = Сбросить мир
|
||||
LayerTitle.Options = Настройки
|
||||
LayerTitle.Quit = Выход
|
||||
|
||||
LayerOptions.Return = Главное меню
|
||||
LayerOptions.Language = Русский
|
||||
|
||||
LayerText.Load = Загрузка...
|
||||
LayerText.Save = Сохранение...
|
BIN
src/main/resources/assets/textures/title/background.png
Normal file
BIN
src/main/resources/assets/textures/title/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 133 B |
BIN
src/main/resources/assets/textures/title/progressia.png
Normal file
BIN
src/main/resources/assets/textures/title/progressia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user