Compare commits
4 Commits
main
...
cb488f9853
| Author | SHA1 | Date | |
|---|---|---|---|
|
cb488f9853
|
|||
|
da45765413
|
|||
|
eef269c853
|
|||
| 6335ab7e5c |
41
.gitignore
vendored
41
.gitignore
vendored
@@ -1 +1,42 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
.kotlin
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
.idea/FuzzierSettings.xml
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
logs
|
logs
|
||||||
|
|||||||
14
.idea/FuzzierSettings.xml
generated
14
.idea/FuzzierSettings.xml
generated
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="com.mituuz.fuzzier.FuzzierSettings">
|
|
||||||
<option name="modules">
|
|
||||||
<map>
|
|
||||||
<entry key="common" value="$PROJECT_DIR$" />
|
|
||||||
<entry key="game" value="$PROJECT_DIR$" />
|
|
||||||
<entry key="game (1)" value="$PROJECT_DIR$" />
|
|
||||||
<entry key="server" value="$PROJECT_DIR$" />
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
<option name="recentlySearchedFiles" value="rO0ABXNyABxqYXZheC5zd2luZy5EZWZhdWx0TGlzdE1vZGVsBgfGCGLvV2ICAAFMAAhkZWxlZ2F0ZXQAEkxqYXZhL3V0aWwvVmVjdG9yO3hyAB1qYXZheC5zd2luZy5BYnN0cmFjdExpc3RNb2RlbFrW+oYSs63tAgABTAAMbGlzdGVuZXJMaXN0dAAlTGphdmF4L3N3aW5nL2V2ZW50L0V2ZW50TGlzdGVuZXJMaXN0O3hwc3IAI2phdmF4LnN3aW5nLmV2ZW50LkV2ZW50TGlzdGVuZXJMaXN0kUjMLXPfDt4DAAB4cHB4c3IAEGphdmEudXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVudERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHAAAAAAAAAAB3VyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAApzcgBIY29tLm1pdHV1ei5mdXp6aWVyLmVudGl0aWVzLkZ1enp5TWF0Y2hDb250YWluZXIkU2VyaWFsaXplZE1hdGNoQ29udGFpbmVy2S8sP5uny74CAARMAAhmaWxlUGF0aHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wACGZpbGVuYW1lcQB+AA1MAA5tb2R1bGVCYXNlUGF0aHEAfgANTAAFc2NvcmV0ADxMY29tL21pdHV1ei9mdXp6aWVyL2VudGl0aWVzL0Z1enp5TWF0Y2hDb250YWluZXIkRnV6enlTY29yZTt4cHQARC9nYW1lL3NyYy9tYWluL2phdmEvY3ovanppdG5pay9jbGllbnQvdXRpbHMvZXZlbnRzL0V2ZW50TWFuYWdlci5qYXZhdAARRXZlbnRNYW5hZ2VyLmphdmF0ABYvaG9tZS9rdWJhL0NvZGluZy9nYW1lc3IAOmNvbS5taXR1dXouZnV6emllci5lbnRpdGllcy5GdXp6eU1hdGNoQ29udGFpbmVyJEZ1enp5U2NvcmUvP9P07ROG2QIABUkADWZpbGVuYW1lU2NvcmVJAA9tdWx0aU1hdGNoU2NvcmVJABBwYXJ0aWFsUGF0aFNjb3JlSQALc3RyZWFrU2NvcmVMABNoaWdobGlnaHRDaGFyYWN0ZXJzdAAPTGphdmEvdXRpbC9TZXQ7eHAAAAAMAAAAAAAAAAoAAAAHc3IAEWphdmEudXRpbC5IYXNoU2V0ukSFlZa4tzQDAAB4cHcMAAAAED9AAAAAAAAMc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAABzcQB+ABgAAAABc3EAfgAYAAAAAnNxAH4AGAAAAANzcQB+ABgAAAAEc3EAfgAYAAAABXNxAH4AGAAAAAZzcQB+ABgAAAAHc3EAfgAYAAAACHNxAH4AGAAAAAlzcQB+ABgAAAAKc3EAfgAYAAAAC3hzcQB+AAx0AEQvZ2FtZS9zcmMvbWFpbi9qYXZhL2N6L2p6aXRuaWsvY2xpZW50L3NvY2tldC9Tb2NrZXRFdmVudE1hbmFnZXIuamF2YXQAF1NvY2tldEV2ZW50TWFuYWdlci5qYXZhdAAWL2hvbWUva3ViYS9Db2RpbmcvZ2FtZXNxAH4AEwAAABEAAAAAAAAAAAAAAApzcQB+ABZ3DAAAACA/QAAAAAAAEXEAfgAacQB+ABtxAH4AHHEAfgAdcQB+AB5xAH4AH3EAfgAgcQB+ACFxAH4AInEAfgAjcQB+ACRxAH4AJXNxAH4AGAAAAAxzcQB+ABgAAAANc3EAfgAYAAAADnNxAH4AGAAAAA9zcQB+ABgAAAAQeHNxAH4ADHQADS9nYW1lL3BvbS54bWx0AAdwb20ueG1sdAAWL2hvbWUva3ViYS9Db2RpbmcvZ2FtZXNxAH4AEwAAAAAAAAAAAAAAAAAAAAxzcQB+ABZ3DAAAAAE/QAAAAAAAAHhzcQB+AAx0AEkvZ2FtZS9zcmMvbWFpbi9qYXZhL2N6L2p6aXRuaWsvY2xpZW50L2Fubm90YXRpb25zL1NvY2tldEV2ZW50SGFuZGxlci5qYXZhdAAXU29ja2V0RXZlbnRIYW5kbGVyLmphdmF0ABYvaG9tZS9rdWJhL0NvZGluZy9nYW1lc3EAfgATAAAAEgAAAAAAAAAKAAAAEHNxAH4AFncMAAAAID9AAAAAAAAScQB+ABpxAH4AG3EAfgAccQB+AB1xAH4AHnEAfgAfcQB+ACBxAH4AIXEAfgAicQB+ACNxAH4AJHEAfgAlcQB+ACxxAH4ALXEAfgAucQB+AC9xAH4AMHNxAH4AGAAAABF4c3EAfgAMdAA/L2dhbWUvc3JjL21haW4vamF2YS9jei9qeml0bmlrL2NsaWVudC9nYW1lL3NldHVwL0dhbWVTZXR1cC5qYXZhdAAOR2FtZVNldHVwLmphdmF0ABYvaG9tZS9rdWJhL0NvZGluZy9nYW1lc3EAfgATAAAADAAAAAAAAAAAAAAABHNxAH4AFncMAAAAED9AAAAAAAAMc3EAfgAYAAAAAHNxAH4AGAAAAAFzcQB+ABgAAAACc3EAfgAYAAAAA3NxAH4AGAAAAARzcQB+ABgAAAAFc3EAfgAYAAAABnNxAH4AGAAAAAdzcQB+ABgAAAAIc3EAfgAYAAAACXNxAH4AGAAAAApzcQB+ABgAAAALeHNxAH4ADHQASS9nYW1lL3NyYy9tYWluL2phdmEvY3ovanppdG5pay9jbGllbnQvZ2FtZS9tb2JzL3Rhc2tzL3V0aWxzL0FTdGFyQWxnLmphdmF0AA1BU3RhckFsZy5qYXZhdAAWL2hvbWUva3ViYS9Db2RpbmcvZ2FtZXNxAH4AEwAAAAgAAAAAAAAACgAAAARzcQB+ABZ3DAAAABA/QAAAAAAACHEAfgBEcQB+AEVxAH4ARnEAfgBHcQB+AEhxAH4ASXEAfgBKcQB+AEt4c3EAfgAMdAA4L2dhbWUvc3JjL21haW4vamF2YS9jei9qeml0bmlrL2NsaWVudC91aS91dGlscy9HcmlkLmphdmF0AAlHcmlkLmphdmF0ABYvaG9tZS9rdWJhL0NvZGluZy9nYW1lc3EAfgATAAAACQAAAAAAAAAAAAAABnNxAH4AFncMAAAAED9AAAAAAAAJcQB+AERxAH4ARXEAfgBGcQB+AEdxAH4ASHEAfgBJcQB+AEpxAH4AS3EAfgBMeHBwcHg=" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
41
.idea/compiler.xml
generated
41
.idea/compiler.xml
generated
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile default="true" name="Default" enabled="true" />
|
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
</profile>
|
|
||||||
<profile name="Annotation profile for common" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<processorPath useClasspath="false">
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.42/lombok-1.18.42.jar" />
|
|
||||||
</processorPath>
|
|
||||||
<module name="common" />
|
|
||||||
</profile>
|
|
||||||
<profile name="Annotation profile for server" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<processorPath useClasspath="false">
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.42/lombok-1.18.42.jar" />
|
|
||||||
</processorPath>
|
|
||||||
<module name="server" />
|
|
||||||
</profile>
|
|
||||||
<profile name="Annotation profile for game-parent" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<processorPath useClasspath="false">
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.38/lombok-1.18.38.jar" />
|
|
||||||
</processorPath>
|
|
||||||
<module name="game (1)" />
|
|
||||||
<module name="game" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/encodings.xml
generated
6
.idea/encodings.xml
generated
@@ -1,12 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Encoding">
|
<component name="Encoding">
|
||||||
<file url="file://$PROJECT_DIR$/common/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/common/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/game/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/game/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/server/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/server/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
25
.idea/jarRepositories.xml
generated
25
.idea/jarRepositories.xml
generated
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Central Repository" />
|
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="be.0110.repo-releases" />
|
|
||||||
<option name="name" value="0110.be repository" />
|
|
||||||
<option name="url" value="https://mvn.0110.be/releases" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
16
.idea/misc.xml
generated
16
.idea/misc.xml
generated
@@ -1,5 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<list size="3">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="cz.jzitnik.annotations.EventHandler" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="cz.jzitnik.annotations.ui.KeyboardPressHandler" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="cz.jzitnik.annotations.ui.MouseHandler" />
|
||||||
|
</list>
|
||||||
|
<writeAnnotations>
|
||||||
|
<writeAnnotation name="cz.jzitnik.annotations.injectors.InjectConfig" />
|
||||||
|
<writeAnnotation name="cz.jzitnik.annotations.injectors.InjectDependency" />
|
||||||
|
<writeAnnotation name="cz.jzitnik.annotations.injectors.InjectState" />
|
||||||
|
</writeAnnotations>
|
||||||
|
</component>
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
@@ -8,5 +20,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
||||||
37
README.md
37
README.md
@@ -1,37 +0,0 @@
|
|||||||
# Terminal Game
|
|
||||||
|
|
||||||
A multiplayer terminal-based game built with Java, utilizing WebSockets for communication and Lanterna for the text-based user interface.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
* **game**: Client application (TUI).
|
|
||||||
* **server**: WebSocket server.
|
|
||||||
* **common**: Shared libraries and logic.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
* Java 25
|
|
||||||
* Maven
|
|
||||||
|
|
||||||
## How to Run
|
|
||||||
|
|
||||||
1. Build the project:
|
|
||||||
```bash
|
|
||||||
mvn clean install
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Start the server:
|
|
||||||
```bash
|
|
||||||
mvn compile exec:java -pl server -am
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Start the client (in a new terminal):
|
|
||||||
```bash
|
|
||||||
mvn compile exec:java -pl game -am
|
|
||||||
```
|
|
||||||
|
|
||||||
## Controls
|
|
||||||
|
|
||||||
* **Left Click**: Interact with objects and fight.
|
|
||||||
* **WASD**: Move the character.
|
|
||||||
* **CTRL**: Hold to run (sprint).
|
|
||||||
39
common/.gitignore
vendored
39
common/.gitignore
vendored
@@ -1,39 +0,0 @@
|
|||||||
target/
|
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
|
||||||
!**/src/main/**/target/
|
|
||||||
!**/src/test/**/target/
|
|
||||||
.kotlin
|
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
|
||||||
.idea/modules.xml
|
|
||||||
.idea/jarRepositories.xml
|
|
||||||
.idea/compiler.xml
|
|
||||||
.idea/libraries/
|
|
||||||
*.iws
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
|
|
||||||
### Eclipse ###
|
|
||||||
.apt_generated
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.springBeans
|
|
||||||
.sts4-cache
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
/nbproject/private/
|
|
||||||
/nbbuild/
|
|
||||||
/dist/
|
|
||||||
/nbdist/
|
|
||||||
/.nb-gradle/
|
|
||||||
build/
|
|
||||||
!**/src/main/**/build/
|
|
||||||
!**/src/test/**/build/
|
|
||||||
|
|
||||||
### VS Code ###
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
### Mac OS ###
|
|
||||||
.DS_Store
|
|
||||||
3
common/.idea/.gitignore
generated
vendored
3
common/.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
7
common/.idea/encodings.xml
generated
7
common/.idea/encodings.xml
generated
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding">
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
14
common/.idea/misc.xml
generated
14
common/.idea/misc.xml
generated
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="MavenProjectsManager">
|
|
||||||
<option name="originalFiles">
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/pom.xml" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
common/.idea/vcs.xml
generated
6
common/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>cz.jzitnik</groupId>
|
|
||||||
<artifactId>game-parent</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>common</artifactId>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.11.0</version>
|
|
||||||
<configuration>
|
|
||||||
<annotationProcessorPaths>
|
|
||||||
<path>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.42</version>
|
|
||||||
</path>
|
|
||||||
</annotationProcessorPaths>
|
|
||||||
<source>25</source>
|
|
||||||
<target>25</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>tools.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>3.0.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>tools.jackson.dataformat</groupId>
|
|
||||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
|
||||||
<version>3.0.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.42</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
<version>2.0.17</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package cz.jzitnik.common;
|
|
||||||
|
|
||||||
public class Config {
|
|
||||||
public static final int WORLD_PASSWORD_LENGTH = 5;
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
package cz.jzitnik.common.models.coordinates;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@ToString
|
|
||||||
@Getter
|
|
||||||
public class RoomCords implements Cloneable, Serializable {
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
|
|
||||||
public RoomCords calculateCenter(BufferedImage texture) {
|
|
||||||
return new RoomCords(
|
|
||||||
x + texture.getWidth() / 2,
|
|
||||||
y + texture.getHeight() / 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public RoomCords(
|
|
||||||
@JsonProperty("x") int x,
|
|
||||||
@JsonProperty("y") int y
|
|
||||||
) {
|
|
||||||
updateCords(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCords(int x, int y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCords(RoomCords roomCords) {
|
|
||||||
updateCords(roomCords.getX(), roomCords.getY());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCordsWithColliders(List<RoomPart> colliders, int x, int y, RoomPart playerCollider) {
|
|
||||||
var normalizedPlayerCollider = new RoomPart(
|
|
||||||
new RoomCords(playerCollider.getStart().getX() + x, playerCollider.getStart().getY() + y),
|
|
||||||
new RoomCords(playerCollider.getEnd().getX() + x, playerCollider.getEnd().getY() + y)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (colliders.stream().anyMatch(collider -> collider.isOverlapping(normalizedPlayerCollider))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateCords(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RoomCords clone() {
|
|
||||||
try {
|
|
||||||
return (RoomCords) super.clone();
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the Euclidean distance between this coordinate and another.
|
|
||||||
*
|
|
||||||
* @param other The other RoomCords instance
|
|
||||||
* @return The distance as a double
|
|
||||||
*/
|
|
||||||
public double calculateDistance(RoomCords other) {
|
|
||||||
if (other == null) {
|
|
||||||
throw new IllegalArgumentException("Cannot calculate distance to null");
|
|
||||||
}
|
|
||||||
return Math.hypot(this.x - other.x, this.y - other.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package cz.jzitnik.common.models.coordinates;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@ToString
|
|
||||||
public class RoomPart implements Serializable {
|
|
||||||
private RoomCords start;
|
|
||||||
private RoomCords end;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public RoomPart(
|
|
||||||
@JsonProperty("start") RoomCords start,
|
|
||||||
@JsonProperty("end") RoomCords end
|
|
||||||
) {
|
|
||||||
this.start = start;
|
|
||||||
this.end = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWithin(RoomCords cords) {
|
|
||||||
return cords.getX() >= start.getX() &&
|
|
||||||
cords.getX() <= end.getX() &&
|
|
||||||
cords.getY() >= start.getY() &&
|
|
||||||
cords.getY() <= end.getY();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this GameRoomPart overlaps with another.
|
|
||||||
*/
|
|
||||||
public boolean isOverlapping(RoomPart other) {
|
|
||||||
return start.getX() <= other.getEnd().getX() &&
|
|
||||||
end.getX() >= other.getStart().getX() &&
|
|
||||||
start.getY() <= other.getEnd().getY() &&
|
|
||||||
end.getY() >= other.getStart().getY();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package cz.jzitnik.common.models.player;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public final class PlayerCreation implements Serializable {
|
|
||||||
@Setter
|
|
||||||
private int id;
|
|
||||||
private final RoomCords playerCords;
|
|
||||||
private final RoomPart collider;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public PlayerCreation(
|
|
||||||
@JsonProperty("playerCords") RoomCords playerCords,
|
|
||||||
@JsonProperty("collider") RoomPart collider
|
|
||||||
) {
|
|
||||||
this.playerCords = playerCords;
|
|
||||||
this.collider = collider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public interface SocketMessage extends Serializable {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public class Test implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record GameWin() implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record PlayerDeath(int playerId) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game.connection;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record ConnectToAGame(String gamePass) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game.connection;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.player.PlayerCreation;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public record ConnectToAGameResponse(ResponseType responseType, PlayerCreation playerCreation, List<PlayerCreation> existingPlayers) implements SocketMessage {
|
|
||||||
private enum ResponseType {
|
|
||||||
GAME_DOES_NOT_EXIST,
|
|
||||||
SUCCESS
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConnectToAGameResponse() {
|
|
||||||
this(ResponseType.GAME_DOES_NOT_EXIST, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConnectToAGameResponse(PlayerCreation playerCreation, List<PlayerCreation> existingPlayers) {
|
|
||||||
this(ResponseType.SUCCESS, playerCreation, existingPlayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean success() {
|
|
||||||
return responseType == ResponseType.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game.creation;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public class CreateGame implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.game.creation;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.player.PlayerCreation;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class CreateGameResponse implements SocketMessage {
|
|
||||||
private final String gamePassword;
|
|
||||||
private final PlayerCreation ownerPlayer;
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.items;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record ItemTookFromChest(
|
|
||||||
String roomId, // For faster lookup i guess
|
|
||||||
int id
|
|
||||||
) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record PlayerArrivalChange(int id, RoomCords playerCords, PlayerRotation playerRotation,
|
|
||||||
boolean arrived, boolean rerender) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record PlayerDisconnected(int playerId) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.player.PlayerCreation;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record PlayerJoined(PlayerCreation playerCreation) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record PlayerMove(RoomCords newCords, PlayerRotation playerRotation) implements SocketMessage {
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class PlayerMovedInUrRoom implements SocketMessage {
|
|
||||||
private int playerId;
|
|
||||||
private RoomCords cords;
|
|
||||||
private PlayerRotation playerRotation;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.player;
|
|
||||||
|
|
||||||
public enum PlayerRotation {
|
|
||||||
FRONT, BACK, LEFT, RIGHT
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.room;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record MovePlayerRoom(String newRoomId, RoomCords oldCords, RoomCords newCords) implements SocketMessage {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package cz.jzitnik.common.socket.messages.room;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerRotation;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public record MovePlayerRoomResponse(Set<Registry> players) implements SocketMessage {
|
|
||||||
public record Registry(int id, RoomCords cords, PlayerRotation playerRotation) implements Serializable {}
|
|
||||||
|
|
||||||
public Optional<Registry> getById(int id) {
|
|
||||||
return players.stream().filter(registry -> registry.id == id).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Integer> getIds() {
|
|
||||||
return players.stream().map(Registry::id).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
42
game/.gitignore
vendored
42
game/.gitignore
vendored
@@ -1,42 +0,0 @@
|
|||||||
target/
|
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
|
||||||
!**/src/main/**/target/
|
|
||||||
!**/src/test/**/target/
|
|
||||||
.kotlin
|
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
|
||||||
.idea/modules.xml
|
|
||||||
.idea/jarRepositories.xml
|
|
||||||
.idea/compiler.xml
|
|
||||||
.idea/libraries/
|
|
||||||
.idea/FuzzierSettings.xml
|
|
||||||
*.iws
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
|
|
||||||
### Eclipse ###
|
|
||||||
.apt_generated
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.springBeans
|
|
||||||
.sts4-cache
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
/nbproject/private/
|
|
||||||
/nbbuild/
|
|
||||||
/dist/
|
|
||||||
/nbdist/
|
|
||||||
/.nb-gradle/
|
|
||||||
build/
|
|
||||||
!**/src/main/**/build/
|
|
||||||
!**/src/test/**/build/
|
|
||||||
|
|
||||||
### VS Code ###
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
### Mac OS ###
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
logs
|
|
||||||
3
game/.idea/.gitignore
generated
vendored
3
game/.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
13
game/.idea/encodings.xml
generated
13
game/.idea/encodings.xml
generated
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding">
|
|
||||||
<file url="file://$PROJECT_DIR$/common/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/common/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/game/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/game/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/server/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/server/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
12
game/.idea/misc.xml
generated
12
game/.idea/misc.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="MavenProjectsManager">
|
|
||||||
<option name="originalFiles">
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/pom.xml" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
|
|
||||||
</project>
|
|
||||||
6
game/.idea/vcs.xml
generated
6
game/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
190
game/pom.xml
190
game/pom.xml
@@ -1,190 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>cz.jzitnik</groupId>
|
|
||||||
<artifactId>game-parent</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>game</artifactId>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.11.0</version>
|
|
||||||
<configuration>
|
|
||||||
<annotationProcessorPaths>
|
|
||||||
<path>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.38</version>
|
|
||||||
</path>
|
|
||||||
</annotationProcessorPaths>
|
|
||||||
<source>25</source>
|
|
||||||
<target>25</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.2.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>cz.jzitnik.client.Main</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>java</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>cz.jzitnik.client.Main</mainClass>
|
|
||||||
<classpathScope>compile</classpathScope>
|
|
||||||
<skip>false</skip>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>be.0110.repo-releases</id>
|
|
||||||
<name>0110.be repository</name>
|
|
||||||
<url>https://mvn.0110.be/releases</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cz.jzitnik</groupId>
|
|
||||||
<artifactId>common</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.42</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.reflections</groupId>
|
|
||||||
<artifactId>reflections</artifactId>
|
|
||||||
<version>0.10.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>33.5.0-jre</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>tools.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>3.0.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>tools.jackson.dataformat</groupId>
|
|
||||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
|
||||||
<version>3.0.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<version>6.0.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
|
||||||
<version>6.0.2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
<version>2.0.17</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<version>1.5.25</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.trilarion</groupId>
|
|
||||||
<artifactId>java-vorbis-support</artifactId>
|
|
||||||
<version>1.2.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.googlecode.lanterna</groupId>
|
|
||||||
<artifactId>lanterna</artifactId>
|
|
||||||
<version>3.1.3</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>javacv-platform</artifactId>
|
|
||||||
<version>1.5.12</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>ffmpeg-platform</artifactId>
|
|
||||||
<version>7.1.1-1.5.12</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>be.tarsos.dsp</groupId>
|
|
||||||
<artifactId>core</artifactId>
|
|
||||||
<version>2.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>be.tarsos.dsp</groupId>
|
|
||||||
<artifactId>jvm</artifactId>
|
|
||||||
<version>2.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish.tyrus.bundles</groupId>
|
|
||||||
<artifactId>tyrus-standalone-client</artifactId>
|
|
||||||
<version>2.2.2</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package cz.jzitnik.client;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.game.setup.GameSetup;
|
|
||||||
import cz.jzitnik.client.socket.Client;
|
|
||||||
import cz.jzitnik.client.socket.SocketEventManager;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.client.utils.GlobalIOHandlerRepository;
|
|
||||||
import cz.jzitnik.client.utils.ScheduledTaskManager;
|
|
||||||
import cz.jzitnik.client.utils.ThreadManager;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import jakarta.websocket.DeploymentException;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Game {
|
|
||||||
private final DependencyManager dependencyManager = new DependencyManager(new Reflections("cz.jzitnik.client"));
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private GameSetup gameSetup;
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
@InjectDependency
|
|
||||||
private SocketEventManager socketEventManager;
|
|
||||||
@InjectDependency
|
|
||||||
private Cli cli;
|
|
||||||
@InjectDependency
|
|
||||||
private ThreadManager threadManager;
|
|
||||||
@InjectDependency
|
|
||||||
private ScheduledTaskManager scheduledTaskManager;
|
|
||||||
@InjectDependency
|
|
||||||
private GlobalIOHandlerRepository globalIOHandlerRepository;
|
|
||||||
|
|
||||||
public void start() throws IOException {
|
|
||||||
dependencyManager.inject(this);
|
|
||||||
|
|
||||||
eventManager.start();
|
|
||||||
socketEventManager.start();
|
|
||||||
|
|
||||||
threadManager.startAll();
|
|
||||||
scheduledTaskManager.startAll();
|
|
||||||
globalIOHandlerRepository.setup();
|
|
||||||
|
|
||||||
gameSetup.setup();
|
|
||||||
|
|
||||||
cli.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package cz.jzitnik.client;
|
|
||||||
|
|
||||||
// events/handlers/MouseMoveEventHandler.java
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
new Game().start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package cz.jzitnik.client.annotations;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public @interface SocketEventHandler {
|
|
||||||
Class<? extends SocketMessage> value();
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package cz.jzitnik.client.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.Config;
|
|
||||||
|
|
||||||
@Config("core_logic.yaml")
|
|
||||||
public record CoreLogic(int itemDropDisappearMinutes) {
|
|
||||||
@JsonCreator
|
|
||||||
public CoreLogic(
|
|
||||||
@JsonProperty("itemDropDisappearMinutes") int itemDropDisappearMinutes
|
|
||||||
) {
|
|
||||||
this.itemDropDisappearMinutes = itemDropDisappearMinutes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package cz.jzitnik.client.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.Config;
|
|
||||||
|
|
||||||
@Config("debugging.yaml")
|
|
||||||
public record Debugging(boolean renderColliders, boolean renderPlayerCollider, boolean showPlayerCordsLogs) {
|
|
||||||
@JsonCreator
|
|
||||||
public Debugging(
|
|
||||||
@JsonProperty("renderColliders") boolean renderColliders,
|
|
||||||
@JsonProperty("renderPlayerCollider") boolean renderPlayerCollider,
|
|
||||||
@JsonProperty("showPlayerCordsLogs") boolean showPlayerCordsLogs
|
|
||||||
) {
|
|
||||||
this.renderColliders = renderColliders;
|
|
||||||
this.renderPlayerCollider = renderPlayerCollider;
|
|
||||||
this.showPlayerCordsLogs = showPlayerCordsLogs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package cz.jzitnik.client.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.Config;
|
|
||||||
|
|
||||||
@Config("microphone.yaml")
|
|
||||||
public record MicrophoneConfig(float volumeThreshold) {
|
|
||||||
@JsonCreator
|
|
||||||
public MicrophoneConfig(
|
|
||||||
@JsonProperty("volumeThreshold") float volumeThreshold
|
|
||||||
) {
|
|
||||||
this.volumeThreshold = volumeThreshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package cz.jzitnik.client.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.Config;
|
|
||||||
import cz.jzitnik.client.events.handlers.PlayerMoveEventHandler;
|
|
||||||
|
|
||||||
@Config("player.yaml")
|
|
||||||
public record PlayerConfig(
|
|
||||||
double playerReach,
|
|
||||||
int playerMoveDistance,
|
|
||||||
int playerMoveDistanceSprinting,
|
|
||||||
PlayerMoveEventHandler.SprintKey sprintKey,
|
|
||||||
int swingTimeMs,
|
|
||||||
int staminaIncreaseRateMs,
|
|
||||||
int staminaDelayMs
|
|
||||||
) {
|
|
||||||
@JsonCreator
|
|
||||||
public PlayerConfig(
|
|
||||||
@JsonProperty("playerReach") double playerReach,
|
|
||||||
@JsonProperty("playerMoveDistance") int playerMoveDistance,
|
|
||||||
@JsonProperty("playerMoveDistanceSprinting") int playerMoveDistanceSprinting,
|
|
||||||
@JsonProperty("sprintKey") PlayerMoveEventHandler.SprintKey sprintKey,
|
|
||||||
@JsonProperty("swingTimeMs") int swingTimeMs,
|
|
||||||
@JsonProperty("staminaIncreaseRateMs") int staminaIncreaseRateMs,
|
|
||||||
@JsonProperty("staminaDelayMs") int staminaDelayMs
|
|
||||||
) {
|
|
||||||
this.playerReach = playerReach;
|
|
||||||
this.playerMoveDistance = playerMoveDistance;
|
|
||||||
this.playerMoveDistanceSprinting = playerMoveDistanceSprinting;
|
|
||||||
this.sprintKey = sprintKey;
|
|
||||||
this.swingTimeMs = swingTimeMs;
|
|
||||||
this.staminaIncreaseRateMs = staminaIncreaseRateMs;
|
|
||||||
this.staminaDelayMs = staminaDelayMs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package cz.jzitnik.client.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.Config;
|
|
||||||
|
|
||||||
@Config("threads.yaml")
|
|
||||||
public record ThreadPoolConfig(int eventThreadCount, int taskThreadCount) {
|
|
||||||
@JsonCreator
|
|
||||||
public ThreadPoolConfig(
|
|
||||||
@JsonProperty("eventThreadCount") int eventThreadCount,
|
|
||||||
@JsonProperty("taskThreadCount") int taskThreadCount
|
|
||||||
) {
|
|
||||||
this.eventThreadCount = eventThreadCount;
|
|
||||||
this.taskThreadCount = taskThreadCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.game.objects.DroppedItem;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public record DroppedItemRerender(DroppedItem droppedItem) implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public class FullRedrawEvent implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public class InventoryRerender implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public class RenderStats implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.events.handlers.FullRoomDrawHandler;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public record RoomChangeEvent(FullRoomDrawHandler.DoorPosition door) implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public record SendSocketMessageEvent(SocketMessage message) implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package cz.jzitnik.client.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
|
|
||||||
public class TerminalTooSmallEvent implements Event {
|
|
||||||
}
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
package cz.jzitnik.client.events.handlers;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.TerminalPosition;
|
|
||||||
import com.googlecode.lanterna.TerminalSize;
|
|
||||||
import com.googlecode.lanterna.TextColor;
|
|
||||||
import cz.jzitnik.client.annotations.EventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.RerenderScreen;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.dialog.Dialog;
|
|
||||||
import cz.jzitnik.client.game.dialog.OnEnd;
|
|
||||||
import cz.jzitnik.client.states.DialogState;
|
|
||||||
import cz.jzitnik.client.states.ScreenBuffer;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.ui.pixels.AlphaPixel;
|
|
||||||
import cz.jzitnik.client.ui.pixels.ColoredPixel;
|
|
||||||
import cz.jzitnik.client.ui.pixels.Empty;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.client.utils.TextRenderer;
|
|
||||||
import cz.jzitnik.client.utils.events.AbstractEventHandler;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@EventHandler(Dialog.class)
|
|
||||||
public class DialogEventHandler extends AbstractEventHandler<Dialog> {
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private DialogState dialogState;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private ScreenBuffer screenBuffer;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private TextRenderer textRenderer;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
private static final int WIDTH = 350;
|
|
||||||
private static final int MARGIN_BOTTOM = 15;
|
|
||||||
public static final int PADDING = 7;
|
|
||||||
private static final int BUTTON_TEXT_PADDING = 4;
|
|
||||||
private static final int QUESTION_ACTIONS_GAP = 10;
|
|
||||||
public static final int BUTTON_HEIGHT = 15;
|
|
||||||
public static final int BUTTON_PADDING = 5;
|
|
||||||
private static final float FONT_SIZE = 15f;
|
|
||||||
|
|
||||||
public static int calculateButtonHeight(Dialog dialog, GameState gameState) {
|
|
||||||
if (dialog.getOnEnd() instanceof OnEnd.AskQuestion askQuestion) {
|
|
||||||
int count = askQuestion.answers(gameState).length;
|
|
||||||
return count * BUTTON_HEIGHT + Math.max(0, count - 1) * BUTTON_PADDING;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getYStartButtons(TextRenderer textRenderer, Dialog dialog) {
|
|
||||||
var textSize = textRenderer.measureText(
|
|
||||||
dialog.getText(),
|
|
||||||
WIDTH - PADDING * 2,
|
|
||||||
FONT_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
return PADDING + textSize.height + BUTTON_PADDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TerminalSize getSize(TextRenderer textRenderer, Dialog dialog, GameState gameState) {
|
|
||||||
var textSize = textRenderer.measureText(
|
|
||||||
dialog.getText(),
|
|
||||||
WIDTH - PADDING * 2,
|
|
||||||
FONT_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
int buttonsHeight = 0;
|
|
||||||
if (dialog.getOnEnd() instanceof OnEnd.AskQuestion) {
|
|
||||||
buttonsHeight = BUTTON_PADDING + calculateButtonHeight(dialog, gameState);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TerminalSize(
|
|
||||||
300,
|
|
||||||
PADDING + textSize.height + buttonsHeight + PADDING
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TerminalPosition getStart(TerminalSize terminalSize, TerminalSize size) {
|
|
||||||
int startY = terminalSize.getRows() * 2 - MARGIN_BOTTOM - size.getRows();
|
|
||||||
int startX = (terminalSize.getColumns() / 2) - (size.getColumns() / 2);
|
|
||||||
return new TerminalPosition(startX, startY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(Dialog event) {
|
|
||||||
boolean onlyLast = dialogState.getCurrentDialog() == event;
|
|
||||||
dialogState.setCurrentDialog(event);
|
|
||||||
|
|
||||||
TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize();
|
|
||||||
var overrideBuffer = screenBuffer.getGlobalOverrideBuffer();
|
|
||||||
var size = getSize(textRenderer, event, gameState);
|
|
||||||
var start = getStart(terminalSize, size);
|
|
||||||
|
|
||||||
var animation = textRenderer.renderTypingAnimation(
|
|
||||||
event.getText(),
|
|
||||||
size.getColumns() - PADDING * 2,
|
|
||||||
size.getRows() - PADDING * 2,
|
|
||||||
Color.WHITE,
|
|
||||||
FONT_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
var textSize = textRenderer.measureText(
|
|
||||||
event.getText(),
|
|
||||||
size.getColumns() - PADDING * 2,
|
|
||||||
FONT_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
OnEnd onEnd = event.getOnEnd();
|
|
||||||
|
|
||||||
List<AlphaPixel[][]> answersBuf = new ArrayList<>();
|
|
||||||
OnEnd.AskQuestion askQuestion = null;
|
|
||||||
|
|
||||||
if (onEnd instanceof OnEnd.AskQuestion aq) {
|
|
||||||
askQuestion = aq;
|
|
||||||
for (OnEnd.AskQuestion.Answer answer : aq.answers(gameState)) {
|
|
||||||
answersBuf.add(
|
|
||||||
textRenderer.renderText(
|
|
||||||
answer.answer(),
|
|
||||||
size.getColumns() - PADDING * 2,
|
|
||||||
BUTTON_HEIGHT,
|
|
||||||
Color.BLACK,
|
|
||||||
FONT_SIZE,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogState.setRenderInProgress(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i = onlyLast ? animation.length : 0; i <= animation.length; i++) {
|
|
||||||
var buf = animation[Math.min(i, animation.length - 1)];
|
|
||||||
|
|
||||||
for (int y = 0; y < size.getRows(); y++) {
|
|
||||||
for (int x = 0; x < size.getColumns(); x++) {
|
|
||||||
|
|
||||||
var textPixel = buf[
|
|
||||||
Math.min(Math.max(0, y - PADDING), buf.length - 1)
|
|
||||||
][
|
|
||||||
Math.min(Math.max(0, x - PADDING), buf[0].length - 1)
|
|
||||||
];
|
|
||||||
|
|
||||||
if (textPixel instanceof Empty
|
|
||||||
|| y < PADDING
|
|
||||||
|| x < PADDING
|
|
||||||
|| x >= size.getColumns() - PADDING
|
|
||||||
|| y >= size.getRows() - PADDING) {
|
|
||||||
|
|
||||||
if (i == animation.length
|
|
||||||
&& askQuestion != null
|
|
||||||
&& y - 2 > textSize.height + QUESTION_ACTIONS_GAP) {
|
|
||||||
|
|
||||||
var answers = askQuestion.answers(gameState);
|
|
||||||
|
|
||||||
int buttonsY = y - textSize.height - QUESTION_ACTIONS_GAP - 2;
|
|
||||||
int buttonIndex = buttonsY / (BUTTON_HEIGHT + BUTTON_PADDING);
|
|
||||||
int rest = buttonsY % (BUTTON_HEIGHT + BUTTON_PADDING);
|
|
||||||
|
|
||||||
if (buttonIndex < answers.length
|
|
||||||
&& rest < BUTTON_HEIGHT
|
|
||||||
&& x >= PADDING
|
|
||||||
&& x < size.getColumns() - PADDING) {
|
|
||||||
|
|
||||||
int localY = rest - BUTTON_TEXT_PADDING;
|
|
||||||
int localX = x - PADDING - BUTTON_TEXT_PADDING;
|
|
||||||
|
|
||||||
var buttonBuf = answersBuf.get(buttonIndex);
|
|
||||||
var buttonTextPixel = buttonBuf[
|
|
||||||
Math.min(Math.max(0, localY), buttonBuf.length - 1)
|
|
||||||
][
|
|
||||||
Math.min(Math.max(0, localX), buttonBuf[0].length - 1)
|
|
||||||
];
|
|
||||||
|
|
||||||
if (buttonTextPixel instanceof Empty
|
|
||||||
|| localY < 0
|
|
||||||
|| localX < 0
|
|
||||||
|| localY >= buttonBuf.length
|
|
||||||
|| localX >= buttonBuf[0].length) {
|
|
||||||
|
|
||||||
overrideBuffer[start.getRow() + y][start.getColumn() + x] =
|
|
||||||
new ColoredPixel(
|
|
||||||
new TextColor.RGB(255, 255, 255),
|
|
||||||
dialogState.getHoveredButtonIndex() == buttonIndex ? 0.8f : 0.6f
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
overrideBuffer[start.getRow() + y][start.getColumn() + x] =
|
|
||||||
buttonTextPixel;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overrideBuffer[start.getRow() + y][start.getColumn() + x] =
|
|
||||||
new ColoredPixel(new TextColor.RGB(0, 0, 0), 0.6f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
overrideBuffer[start.getRow() + y][start.getColumn() + x] = textPixel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventManager.emitEvent(
|
|
||||||
new RerenderScreen(
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
start,
|
|
||||||
new TerminalPosition(
|
|
||||||
start.getColumn() + size.getColumns(),
|
|
||||||
start.getRow() + size.getRows()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Thread.sleep(1000 / event.getTypingSpeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogState.setRenderInProgress(false);
|
|
||||||
next(onEnd, start, size);
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void next(OnEnd onEnd, TerminalPosition start, TerminalSize size) throws InterruptedException {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
if (onEnd instanceof OnEnd.Continue(Dialog nextDialog)) {
|
|
||||||
clear(start, size);
|
|
||||||
eventManager.emitEvent(nextDialog);
|
|
||||||
|
|
||||||
} else if (onEnd instanceof OnEnd.RunCode runCode) {
|
|
||||||
Runnable runnable = runCode.getRunnable();
|
|
||||||
dependencyManager.inject(runnable);
|
|
||||||
runnable.run();
|
|
||||||
next(runCode.getOnEnd(), start, size);
|
|
||||||
} else if (onEnd instanceof OnEnd.End) {
|
|
||||||
clear(start, size);
|
|
||||||
dialogState.setCurrentDialog(null);
|
|
||||||
eventManager.emitEvent(
|
|
||||||
new RerenderScreen(
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
start,
|
|
||||||
new TerminalPosition(
|
|
||||||
start.getColumn() + size.getColumns(),
|
|
||||||
start.getRow() + size.getRows()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clear(TerminalPosition start, TerminalSize size) {
|
|
||||||
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) {
|
|
||||||
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) {
|
|
||||||
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package cz.jzitnik.client.events.handlers;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.EventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.ExitEvent;
|
|
||||||
import cz.jzitnik.client.states.RunningState;
|
|
||||||
import cz.jzitnik.client.utils.ScheduledTaskManager;
|
|
||||||
import cz.jzitnik.client.utils.ThreadManager;
|
|
||||||
import cz.jzitnik.client.utils.events.AbstractEventHandler;
|
|
||||||
import cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler;
|
|
||||||
|
|
||||||
@EventHandler(ExitEvent.class)
|
|
||||||
public class ExitEventHandler extends AbstractEventHandler<ExitEvent> {
|
|
||||||
@InjectDependency
|
|
||||||
private ThreadManager threadManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private RunningState runningState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private RoomTaskScheduler roomTaskScheduler;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ScheduledTaskManager scheduledTaskManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ExitEvent event) {
|
|
||||||
threadManager.shutdownAll();
|
|
||||||
scheduledTaskManager.shutdown();
|
|
||||||
roomTaskScheduler.finalShutdown();
|
|
||||||
runningState.setRunning(false);
|
|
||||||
//System.exit(0); // Pls don't blame me
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package cz.jzitnik.client.events.handlers;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.EventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.RoomChangeEvent;
|
|
||||||
import cz.jzitnik.client.events.SendSocketMessageEvent;
|
|
||||||
import cz.jzitnik.client.game.GameRoom;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.Requirement;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.utils.events.AbstractEventHandler;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.GameWin;
|
|
||||||
import cz.jzitnik.common.socket.messages.room.MovePlayerRoom;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@EventHandler(RoomChangeEvent.class)
|
|
||||||
public class RoomChangeEventHandler extends AbstractEventHandler<RoomChangeEvent> {
|
|
||||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
@InjectDependency
|
|
||||||
private RoomTaskScheduler roomTaskScheduler;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(RoomChangeEvent event) {
|
|
||||||
RoomCords playerCords = gameState.getPlayer().getPlayerCords();
|
|
||||||
RoomCords oldCords = playerCords.clone();
|
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
|
||||||
GameRoom newRoom = switch (event.door()) {
|
|
||||||
case LEFT -> currentRoom.getLeft();
|
|
||||||
case RIGHT -> currentRoom.getRight();
|
|
||||||
case TOP -> currentRoom.getUp();
|
|
||||||
case BOTTOM -> currentRoom.getDown();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (newRoom == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newRoom.getRequirement() != null) {
|
|
||||||
Requirement requirement = newRoom.getRequirement();
|
|
||||||
String itemType = requirement.itemType();
|
|
||||||
if (Arrays.stream(gameState.getPlayer().getInventory()).noneMatch(item -> {
|
|
||||||
if (item == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return item.getType().getItemType().getSimpleName().equals(itemType);
|
|
||||||
})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.door()) {
|
|
||||||
case LEFT -> playerCords.updateCords(155, playerCords.getY());
|
|
||||||
case RIGHT -> playerCords.updateCords(30, playerCords.getY());
|
|
||||||
case TOP -> playerCords.updateCords(playerCords.getX(), 110);
|
|
||||||
case BOTTOM -> playerCords.updateCords(playerCords.getX(), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventManager.emitEvent(new SendSocketMessageEvent(new MovePlayerRoom(newRoom.getId(), oldCords, playerCords)));
|
|
||||||
|
|
||||||
gameState.setCurrentRoom(newRoom);
|
|
||||||
if (newRoom.isEnd()) {
|
|
||||||
eventManager.emitEvent(new SendSocketMessageEvent(new GameWin()));
|
|
||||||
} else {
|
|
||||||
scheduler.schedule(() -> roomTaskScheduler.setupNewSchedulers(newRoom), 200, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package cz.jzitnik.client.events.handlers;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.EventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.events.SendSocketMessageEvent;
|
|
||||||
import cz.jzitnik.client.socket.Client;
|
|
||||||
import cz.jzitnik.client.utils.events.AbstractEventHandler;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@EventHandler(SendSocketMessageEvent.class)
|
|
||||||
public class SendSocketMessageEventHandler extends AbstractEventHandler<SendSocketMessageEvent> {
|
|
||||||
@InjectDependency
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(SendSocketMessageEvent event) {
|
|
||||||
try {
|
|
||||||
client.send(event.message());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package cz.jzitnik.client.game;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
public interface GamePlayer {
|
|
||||||
RoomCords getPlayerCords();
|
|
||||||
BufferedImage getTexture(ResourceManager resourceManager);
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package cz.jzitnik.client.game;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.*;
|
|
||||||
import cz.jzitnik.client.game.mobs.Mob;
|
|
||||||
import cz.jzitnik.client.game.objects.DroppedItem;
|
|
||||||
import cz.jzitnik.client.game.objects.GameObject;
|
|
||||||
import cz.jzitnik.client.ui.pixels.Empty;
|
|
||||||
import cz.jzitnik.client.ui.pixels.Pixel;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@JsonIdentityInfo(
|
|
||||||
generator = ObjectIdGenerators.PropertyGenerator.class,
|
|
||||||
property = "id"
|
|
||||||
)
|
|
||||||
@Getter
|
|
||||||
public class GameRoom {
|
|
||||||
private final String id;
|
|
||||||
@JsonIgnore
|
|
||||||
private final Pixel[][] overrideBuffer;
|
|
||||||
@JsonIgnore
|
|
||||||
private final ResourceManager.Resource texture;
|
|
||||||
@JsonIgnore
|
|
||||||
private final List<GameObject> objects = new ArrayList<>();
|
|
||||||
@JsonIgnore
|
|
||||||
private final List<Mob> mobs = new ArrayList<>();
|
|
||||||
@JsonIgnore
|
|
||||||
private final Set<DroppedItem> droppedItems = new HashSet<>();
|
|
||||||
@JsonIgnore
|
|
||||||
private final List<RoomPart> colliders = new ArrayList<>();
|
|
||||||
|
|
||||||
@JsonProperty("requirement")
|
|
||||||
private Requirement requirement;
|
|
||||||
|
|
||||||
@JsonProperty("end")
|
|
||||||
private boolean end;
|
|
||||||
|
|
||||||
private GameRoom left;
|
|
||||||
private GameRoom right;
|
|
||||||
private GameRoom up;
|
|
||||||
private GameRoom down;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public GameRoom(
|
|
||||||
@JsonProperty("id") String id,
|
|
||||||
@JsonProperty("objects") List<GameObject> objects,
|
|
||||||
@JsonProperty("colliders") List<RoomPart> colliders,
|
|
||||||
@JsonProperty("mobs") List<Mob> mobs,
|
|
||||||
@JsonProperty("texture") ResourceManager.Resource texture
|
|
||||||
) {
|
|
||||||
this.id = id;
|
|
||||||
this.texture = texture;
|
|
||||||
|
|
||||||
if (objects != null) this.objects.addAll(objects);
|
|
||||||
if (colliders != null) this.colliders.addAll(colliders);
|
|
||||||
if (mobs != null) this.mobs.addAll(mobs);
|
|
||||||
|
|
||||||
int height = 225;
|
|
||||||
int width = 225 * 2;
|
|
||||||
|
|
||||||
Pixel[][] overrideBuffer = new Pixel[height][width];
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
overrideBuffer[y][x] = new Empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.overrideBuffer = overrideBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSetter("west")
|
|
||||||
public void setWest(GameRoom west) {
|
|
||||||
if (west != null) this.left = west;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSetter("east")
|
|
||||||
public void setEast(GameRoom east) {
|
|
||||||
if (east != null) this.right = east;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSetter("north")
|
|
||||||
public void setNorth(GameRoom north) {
|
|
||||||
if (north != null) this.up = north;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSetter("south")
|
|
||||||
public void setSouth(GameRoom south) {
|
|
||||||
if (south != null) this.down = south;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package cz.jzitnik.client.game;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.State;
|
|
||||||
import cz.jzitnik.client.game.objects.Interactable;
|
|
||||||
import cz.jzitnik.client.screens.Screen;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@State
|
|
||||||
public class GameState {
|
|
||||||
private final DependencyManager dependencyManager; // Maybe transient in the future
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private GameRoom currentRoom;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private List<GameRoom> allRooms;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private Player player;
|
|
||||||
|
|
||||||
private final List<OtherPlayer> otherPlayers = new ArrayList<>();
|
|
||||||
|
|
||||||
public List<OtherPlayer> getOtherPlayers() {
|
|
||||||
return otherPlayers.stream().filter(OtherPlayer::isVisible).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<OtherPlayer> getAllOtherPlayers() {
|
|
||||||
return otherPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private Interactable interacting;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private Screen screen;
|
|
||||||
|
|
||||||
public void setScreen(Screen screen) {
|
|
||||||
if (screen != null) {
|
|
||||||
dependencyManager.inject(screen);
|
|
||||||
}
|
|
||||||
this.screen = screen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package cz.jzitnik.client.game;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.game.mobs.HittableMob;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.common.models.player.PlayerCreation;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerRotation;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class OtherPlayer implements GamePlayer {
|
|
||||||
private final int id;
|
|
||||||
private boolean hitAnimationOn = false;
|
|
||||||
private final RoomCords playerCords;
|
|
||||||
@Setter
|
|
||||||
private PlayerRotation playerRotation = PlayerRotation.FRONT;
|
|
||||||
@Setter
|
|
||||||
private boolean visible;
|
|
||||||
|
|
||||||
public OtherPlayer(PlayerCreation playerCreation) {
|
|
||||||
this.id = playerCreation.getId();
|
|
||||||
this.playerCords = playerCreation.getPlayerCords();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage getTexture(ResourceManager resourceManager) {
|
|
||||||
BufferedImage resource = resourceManager.getResource(switch (playerRotation) {
|
|
||||||
case FRONT -> ResourceManager.Resource.PLAYER_FRONT;
|
|
||||||
case BACK -> ResourceManager.Resource.PLAYER_BACK;
|
|
||||||
case LEFT -> ResourceManager.Resource.PLAYER_LEFT;
|
|
||||||
case RIGHT -> ResourceManager.Resource.PLAYER_RIGHT;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hitAnimationOn) {
|
|
||||||
return HittableMob.applyRedFactor(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package cz.jzitnik.client.game;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
public record Requirement(String itemType) {
|
|
||||||
@JsonCreator
|
|
||||||
public Requirement(
|
|
||||||
@JsonProperty("item") String itemType
|
|
||||||
) {
|
|
||||||
this.itemType = itemType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.dialog;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class Dialog implements Event {
|
|
||||||
/**
|
|
||||||
* Characters per second
|
|
||||||
*/
|
|
||||||
private final int typingSpeed = 10;
|
|
||||||
private final String text;
|
|
||||||
private final OnEnd onEnd;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public Dialog(
|
|
||||||
@JsonProperty("text") String text,
|
|
||||||
@JsonProperty("onEnd") OnEnd onEnd
|
|
||||||
) {
|
|
||||||
this.text = text;
|
|
||||||
this.onEnd = onEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.dialog;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.InventoryRerender;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.Player;
|
|
||||||
import cz.jzitnik.client.game.Requirement;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.game.items.GameItem;
|
|
||||||
import cz.jzitnik.client.game.mobs.HittableMobDrops;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@JsonTypeInfo(
|
|
||||||
use = JsonTypeInfo.Id.NAME,
|
|
||||||
property = "type"
|
|
||||||
)
|
|
||||||
@JsonSubTypes({
|
|
||||||
@JsonSubTypes.Type(value = OnEnd.Continue.class, name = "continue"),
|
|
||||||
@JsonSubTypes.Type(value = OnEnd.AskQuestion.class, name = "ask_question"),
|
|
||||||
@JsonSubTypes.Type(value = OnEnd.End.class, name = "end"),
|
|
||||||
@JsonSubTypes.Type(value = OnEnd.GiveItem.class, name = "give_item")
|
|
||||||
})
|
|
||||||
public interface OnEnd {
|
|
||||||
record End() implements OnEnd {
|
|
||||||
}
|
|
||||||
|
|
||||||
class GiveItem extends RunCode {
|
|
||||||
@JsonCreator
|
|
||||||
public GiveItem(
|
|
||||||
@JsonProperty("item") GameItem item,
|
|
||||||
@JsonProperty("then") OnEnd onEnd
|
|
||||||
) {
|
|
||||||
super(new Run(item), onEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
private static class Run implements Runnable {
|
|
||||||
private final GameItem item;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ResourceManager resourceManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Player player = gameState.getPlayer();
|
|
||||||
var playerCords = player.getPlayerCords().calculateCenter(player.getTexture(resourceManager));
|
|
||||||
|
|
||||||
boolean addedIntoInventory = player.addItem(item);
|
|
||||||
|
|
||||||
if (!addedIntoInventory) {
|
|
||||||
eventManager.emitEvent(HittableMobDrops.dropItem(playerCords.getX(), playerCords.getY(), gameState.getCurrentRoom(), item));
|
|
||||||
} else {
|
|
||||||
eventManager.emitEvent(new InventoryRerender());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
class RunCode implements OnEnd {
|
|
||||||
private final Runnable runnable;
|
|
||||||
private final OnEnd onEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
record Continue(Dialog nextDialog) implements OnEnd {
|
|
||||||
@JsonCreator
|
|
||||||
public Continue(@JsonProperty("nextDialog") Dialog nextDialog) {
|
|
||||||
this.nextDialog = nextDialog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
record AskQuestion(Answer[] answers) implements OnEnd {
|
|
||||||
@JsonCreator
|
|
||||||
public AskQuestion(@JsonProperty("answers") Answer[] answers) {
|
|
||||||
this.answers = answers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public record Answer(
|
|
||||||
String answer,
|
|
||||||
Dialog dialog,
|
|
||||||
Optional<Requirement> requirement
|
|
||||||
) {
|
|
||||||
@JsonCreator
|
|
||||||
public Answer(
|
|
||||||
@JsonProperty("answer") String answer,
|
|
||||||
@JsonProperty("dialog") Dialog dialog,
|
|
||||||
@JsonProperty("requirement") Requirement requirement
|
|
||||||
) {
|
|
||||||
this(answer, dialog, Optional.ofNullable(requirement));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValid(GameState gameState) {
|
|
||||||
if (requirement.isPresent()) {
|
|
||||||
Requirement requirement = requirement().get();
|
|
||||||
if (requirement.itemType() != null) {
|
|
||||||
return Arrays.stream(gameState.getPlayer().getInventory()).anyMatch(item -> {
|
|
||||||
if (item == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return item.getType().getItemType().getSimpleName().equals(requirement.itemType());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Answer[] answers(GameState gameState) {
|
|
||||||
return Arrays.stream(answers)
|
|
||||||
.filter(answer -> answer.isValid(gameState))
|
|
||||||
.toArray(Answer[]::new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.*;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.game.items.types.ItemType;
|
|
||||||
import cz.jzitnik.client.game.utils.Renderable;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class GameItem implements Renderable {
|
|
||||||
private final ItemType<?> type;
|
|
||||||
@JsonIgnore
|
|
||||||
private final BufferedImage texture;
|
|
||||||
private final String name;
|
|
||||||
private final int id;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public GameItem(
|
|
||||||
@JsonProperty("id") int id,
|
|
||||||
@JsonProperty("name") String name,
|
|
||||||
@JsonProperty("type") ItemType<?> type,
|
|
||||||
@JsonProperty("texture") ResourceManager.Resource resource,
|
|
||||||
@JacksonInject ResourceManager resourceManager
|
|
||||||
) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
this.texture = resourceManager.getResource(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types;
|
|
||||||
|
|
||||||
public class BeastSkin implements ItemType<BeastSkin> {
|
|
||||||
@Override
|
|
||||||
public Class<BeastSkin> getItemType() {
|
|
||||||
return BeastSkin.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import cz.jzitnik.client.game.items.types.food.Food;
|
|
||||||
import cz.jzitnik.client.game.items.types.weapons.Sword;
|
|
||||||
|
|
||||||
@JsonTypeInfo(
|
|
||||||
use = JsonTypeInfo.Id.NAME,
|
|
||||||
property = "name"
|
|
||||||
)
|
|
||||||
@JsonSubTypes({
|
|
||||||
@JsonSubTypes.Type(value = Food.class, name = "food"),
|
|
||||||
@JsonSubTypes.Type(value = Sword.class, name = "weapon_sword"),
|
|
||||||
@JsonSubTypes.Type(value = Junk.class, name = "junk"),
|
|
||||||
@JsonSubTypes.Type(value = Key.class, name = "key"),
|
|
||||||
@JsonSubTypes.Type(value = BeastSkin.class, name = "beast_skin"),
|
|
||||||
})
|
|
||||||
public interface ItemType<T> {
|
|
||||||
Class<T> getItemType();
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types;
|
|
||||||
|
|
||||||
public class Junk implements ItemType<Junk> {
|
|
||||||
@Override
|
|
||||||
public Class<Junk> getItemType() {
|
|
||||||
return Junk.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types;
|
|
||||||
|
|
||||||
public class Key implements ItemType<Key> {
|
|
||||||
@Override
|
|
||||||
public Class<Key> getItemType() {
|
|
||||||
return Key.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types.weapons;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
public class Sword extends Weapon {
|
|
||||||
@JsonCreator
|
|
||||||
public Sword(
|
|
||||||
@JsonProperty("dealDamage") int dealDamage
|
|
||||||
) {
|
|
||||||
super(dealDamage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.items.types.weapons;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.game.items.types.ItemType;
|
|
||||||
import cz.jzitnik.client.game.items.types.interfaces.WeaponInterface;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
public abstract class Weapon implements ItemType<Weapon>, WeaponInterface {
|
|
||||||
private final int dealDamage;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Class<Weapon> getItemType() {
|
|
||||||
return Weapon.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDamageDeal() {
|
|
||||||
return dealDamage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import cz.jzitnik.client.game.dialog.Dialog;
|
|
||||||
import cz.jzitnik.client.game.mobs.tasks.MobRoomTask;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.states.DialogState;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class DialogMob extends Mob {
|
|
||||||
protected Dialog dialog;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public DialogMob(
|
|
||||||
@JsonProperty("texture") ResourceManager.Resource texture,
|
|
||||||
@JsonProperty("tasks") MobRoomTask[] tasks,
|
|
||||||
@JsonProperty("cords") RoomCords cords,
|
|
||||||
@JsonProperty("collider") RoomPart collider,
|
|
||||||
@JsonProperty("dialog") Dialog dialog,
|
|
||||||
@JacksonInject ResourceManager resourceManager
|
|
||||||
) {
|
|
||||||
super(resourceManager.getResource(texture), tasks, cords, collider);
|
|
||||||
this.dialog = dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private DialogState dialogState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void interact() {
|
|
||||||
log.debug("Interacting with dialog mob!");
|
|
||||||
if (dialogState.getCurrentDialog() == null) {
|
|
||||||
eventManager.emitEvent(dialog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.DroppedItemRerender;
|
|
||||||
import cz.jzitnik.client.events.InventoryRerender;
|
|
||||||
import cz.jzitnik.client.game.*;
|
|
||||||
import cz.jzitnik.client.game.items.GameItem;
|
|
||||||
import cz.jzitnik.client.game.mobs.tasks.MobRoomTask;
|
|
||||||
import cz.jzitnik.client.game.objects.DroppedItem;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
|
|
||||||
public class HittableMobDrops extends HittableMob {
|
|
||||||
private static final int DROP_ITEM_ON_GROUND_RADIUS = 30;
|
|
||||||
private final GameItem[] itemsDrops;
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public HittableMobDrops(
|
|
||||||
@JsonProperty("texture") ResourceManager.Resource texture,
|
|
||||||
@JsonProperty("tasks") MobRoomTask[] tasks,
|
|
||||||
@JsonProperty("cords") RoomCords cords,
|
|
||||||
@JsonProperty("collider") RoomPart collider,
|
|
||||||
@JsonProperty("health") int health,
|
|
||||||
@JsonProperty("itemsDrops") GameItem[] itemsDrops,
|
|
||||||
@JacksonInject ResourceManager resourceManager
|
|
||||||
) {
|
|
||||||
super(resourceManager.getResource(texture), tasks, cords, collider, health);
|
|
||||||
this.itemsDrops = itemsDrops == null ? new GameItem[]{} : itemsDrops;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can be overwritten by an extending class
|
|
||||||
**/
|
|
||||||
public void afterKill() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onKilled() {
|
|
||||||
boolean addedIntoInventory = false;
|
|
||||||
Player player = gameState.getPlayer();
|
|
||||||
RoomCords enemyCords = getCords();
|
|
||||||
BufferedImage enemyTexture = getTexture();
|
|
||||||
int roomX = enemyCords.getX() + enemyTexture.getWidth() / 2;
|
|
||||||
int roomY = enemyCords.getY() + enemyTexture.getHeight() / 2;
|
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
|
||||||
|
|
||||||
List<Event> events = new ArrayList<>();
|
|
||||||
|
|
||||||
for (GameItem item : itemsDrops) {
|
|
||||||
boolean added = player.addItem(item);
|
|
||||||
|
|
||||||
if (added) {
|
|
||||||
if (!addedIntoInventory) {
|
|
||||||
addedIntoInventory = true;
|
|
||||||
events.add(new InventoryRerender());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
events.add(dropItem(roomX, roomY, currentRoom, item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventManager.emitEvent(events, this::afterKill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Event dropItem(int x, int y, GameRoom currentRoom, GameItem item) {
|
|
||||||
double angle = ThreadLocalRandom.current().nextDouble(0, Math.PI * 2);
|
|
||||||
double radius = ThreadLocalRandom.current().nextDouble(0, DROP_ITEM_ON_GROUND_RADIUS);
|
|
||||||
int randomX = x + (int) (Math.cos(angle) * radius);
|
|
||||||
int randomY = y + (int) (Math.sin(angle) * radius);
|
|
||||||
RoomCords itemCords = new RoomCords(randomX, randomY);
|
|
||||||
DroppedItem droppedItem = new DroppedItem(currentRoom, itemCords, item);
|
|
||||||
currentRoom.getDroppedItems().add(droppedItem);
|
|
||||||
return new DroppedItemRerender(droppedItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.game.mobs.tasks.MobRoomTask;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
|
|
||||||
public class HittableMobNoDrops extends HittableMob {
|
|
||||||
@JsonCreator
|
|
||||||
public HittableMobNoDrops(
|
|
||||||
@JsonProperty("texture") ResourceManager.Resource texture,
|
|
||||||
@JsonProperty("tasks") MobRoomTask[] tasks,
|
|
||||||
@JsonProperty("cords") RoomCords cords,
|
|
||||||
@JsonProperty("collider") RoomPart collider,
|
|
||||||
@JsonProperty("health") int health,
|
|
||||||
@JacksonInject ResourceManager resourceManager
|
|
||||||
) {
|
|
||||||
super(resourceManager.getResource(texture), tasks, cords, collider, health);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKilled() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomPart;
|
|
||||||
import cz.jzitnik.client.game.mobs.tasks.MobRoomTask;
|
|
||||||
import cz.jzitnik.client.game.utils.Renderable;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.game.utils.Selectable;
|
|
||||||
import cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@JsonTypeInfo(
|
|
||||||
use = JsonTypeInfo.Id.NAME,
|
|
||||||
property = "type"
|
|
||||||
)
|
|
||||||
@JsonSubTypes({
|
|
||||||
@JsonSubTypes.Type(value = DialogMob.class, name = "dialog"),
|
|
||||||
@JsonSubTypes.Type(value = HittableMobDrops.class, name = "hittable_drops"),
|
|
||||||
@JsonSubTypes.Type(value = HittableMobNoDrops.class, name = "hittable_no_drops")
|
|
||||||
})
|
|
||||||
@Getter
|
|
||||||
public abstract class Mob implements Renderable, Selectable {
|
|
||||||
@JsonIgnore
|
|
||||||
protected final BufferedImage texture;
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
protected MobRoomTask[] tasks;
|
|
||||||
@JsonIgnore
|
|
||||||
protected final RoomCords cords;
|
|
||||||
@JsonIgnore
|
|
||||||
protected final RoomPart collider;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private RoomTaskScheduler roomTaskScheduler;
|
|
||||||
|
|
||||||
protected void updateTasks(MobRoomTask[] tasks) {
|
|
||||||
var oldTasks = this.tasks;
|
|
||||||
this.tasks = tasks;
|
|
||||||
|
|
||||||
roomTaskScheduler.registerNewMob(this, oldTasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mob(BufferedImage texture, MobRoomTask[] tasks, RoomCords cords, RoomPart collider) {
|
|
||||||
this.texture = texture;
|
|
||||||
this.tasks = tasks == null ? new MobRoomTask[] {} : tasks;
|
|
||||||
this.cords = cords;
|
|
||||||
this.collider = collider;
|
|
||||||
|
|
||||||
if (tasks != null) {
|
|
||||||
for (MobRoomTask task : tasks) {
|
|
||||||
task.setOwner(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
private boolean selected = false;
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs.tasks;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectConfig;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.config.Debugging;
|
|
||||||
import cz.jzitnik.client.config.MicrophoneConfig;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.game.mobs.Mob;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.states.MicrophoneState;
|
|
||||||
import cz.jzitnik.client.states.ScreenBuffer;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class BlindMobFollowingPlayerTask extends MobRoomTask {
|
|
||||||
private final Task task;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public BlindMobFollowingPlayerTask(
|
|
||||||
@JsonProperty("speed") int speed,
|
|
||||||
@JsonProperty("updateRateMs") int updateRateMs
|
|
||||||
) {
|
|
||||||
Task task = new Task(speed);
|
|
||||||
super(task, updateRateMs, TimeUnit.MILLISECONDS);
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOwner(Mob mob) {
|
|
||||||
task.setMob(mob);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
private static class Task implements Runnable {
|
|
||||||
@Setter
|
|
||||||
private Mob mob;
|
|
||||||
private final int speed;
|
|
||||||
private RoomCords playerCords;
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ResourceManager resourceManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private ScreenBuffer screenBuffer;
|
|
||||||
|
|
||||||
@InjectConfig
|
|
||||||
private Debugging debugging;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private MicrophoneState microphoneState;
|
|
||||||
|
|
||||||
@InjectConfig
|
|
||||||
private MicrophoneConfig microphoneConfig;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (playerCords == null || (microphoneState.isMicrophoneSetup() && microphoneState.getMicrophoneVolume() > microphoneConfig.volumeThreshold())) {
|
|
||||||
playerCords = gameState.getPlayer().getPlayerCords().clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
MobFollowingPlayerTask.Task.moveMob(playerCords, mob, gameState, speed, resourceManager, terminalState, screenBuffer, debugging, eventManager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs.tasks;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.RenderStats;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.mobs.Mob;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class EnemyPlayerAttackingTask extends MobRoomTask {
|
|
||||||
private final Task task;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public EnemyPlayerAttackingTask(
|
|
||||||
@JsonProperty("updateRateMs") long updateRateMs,
|
|
||||||
@JsonProperty("reach") double reach,
|
|
||||||
@JsonProperty("damage") int damage
|
|
||||||
) {
|
|
||||||
Task task = new Task(reach, damage);
|
|
||||||
super(task, updateRateMs, TimeUnit.MILLISECONDS);
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOwner(Mob mob) {
|
|
||||||
task.setMob(mob);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
private static class Task implements Runnable {
|
|
||||||
private final double reach;
|
|
||||||
private final int damage;
|
|
||||||
@Setter
|
|
||||||
private Mob mob;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
RoomCords playerCords = gameState.getPlayer().getPlayerCords();
|
|
||||||
RoomCords mobCords = mob.getCords();
|
|
||||||
double distance = playerCords.calculateDistance(mobCords);
|
|
||||||
|
|
||||||
if (distance > reach) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isDead = gameState.getPlayer().dealDamage(damage, dependencyManager);
|
|
||||||
eventManager.emitEvent(new RenderStats());
|
|
||||||
|
|
||||||
log.debug("Is dead: {}", isDead);
|
|
||||||
// TODO: Death screen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.mobs.tasks;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import cz.jzitnik.client.game.mobs.Mob;
|
|
||||||
import cz.jzitnik.client.utils.roomtasks.RoomTask;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
|
|
||||||
@JsonTypeInfo(
|
|
||||||
use = JsonTypeInfo.Id.NAME,
|
|
||||||
property = "type"
|
|
||||||
)
|
|
||||||
@JsonSubTypes({
|
|
||||||
@JsonSubTypes.Type(value = BlindMobFollowingPlayerTask.class, name = "blind_following_player"),
|
|
||||||
@JsonSubTypes.Type(value = MobFollowingPlayerTask.class, name = "following_player"),
|
|
||||||
@JsonSubTypes.Type(value = EnemyPlayerAttackingTask.class, name = "attacking_player")
|
|
||||||
})
|
|
||||||
public abstract class MobRoomTask extends RoomTask {
|
|
||||||
public MobRoomTask(Runnable task, long rate, TimeUnit rateUnit) {
|
|
||||||
super(task, rate, rateUnit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void setOwner(Mob mob);
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.objects;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
||||||
import cz.jzitnik.client.game.utils.Renderable;
|
|
||||||
import cz.jzitnik.common.models.coordinates.RoomCords;
|
|
||||||
import cz.jzitnik.client.game.utils.Selectable;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@JsonTypeInfo(
|
|
||||||
use = JsonTypeInfo.Id.NAME,
|
|
||||||
property = "objectType"
|
|
||||||
)
|
|
||||||
@JsonSubTypes({
|
|
||||||
@JsonSubTypes.Type(value = Chest.class, name = "chest")
|
|
||||||
})
|
|
||||||
public sealed abstract class GameObject implements Renderable, Selectable permits Chest {
|
|
||||||
@JsonIgnore
|
|
||||||
private final BufferedImage texture;
|
|
||||||
@JsonIgnore
|
|
||||||
private final RoomCords cords;
|
|
||||||
@JsonIgnore
|
|
||||||
private final boolean selectable;
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
@Setter
|
|
||||||
private boolean selected = false;
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.setup;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.Dependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.SendSocketMessageEvent;
|
|
||||||
import cz.jzitnik.client.game.GameRoom;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.Player;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.game.setup.scenes.connect.ServerChoose;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.creation.CreateGame;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import tools.jackson.core.type.TypeReference;
|
|
||||||
import tools.jackson.databind.ObjectMapper;
|
|
||||||
import tools.jackson.databind.ObjectReader;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Dependency
|
|
||||||
public class GameSetup {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ResourceManager resourceManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
public void setup() throws IOException {
|
|
||||||
gameState.setScreen(new ServerChoose(dependencyManager));
|
|
||||||
|
|
||||||
ObjectReader roomsReader = objectMapper.readerFor(
|
|
||||||
new TypeReference<List<GameRoom>>() {
|
|
||||||
}
|
|
||||||
).with(dependencyManager);
|
|
||||||
List<GameRoom> rooms = roomsReader.readValue(
|
|
||||||
resourceManager.getResourceAsStream("setup/rooms.yaml")
|
|
||||||
);
|
|
||||||
|
|
||||||
gameState.setCurrentRoom(rooms.getFirst());
|
|
||||||
gameState.setAllRooms(rooms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.setup.scenes;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.screens.DeathScreen;
|
|
||||||
import cz.jzitnik.client.screens.Screen;
|
|
||||||
import cz.jzitnik.client.screens.scenes.Scene;
|
|
||||||
|
|
||||||
public class DeathScene extends Scene {
|
|
||||||
public DeathScene() {
|
|
||||||
super(new Screen[]{new DeathScreen()}, new OnEndAction.Repeat());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.setup.scenes;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.screens.WinScreen;
|
|
||||||
import cz.jzitnik.client.screens.Screen;
|
|
||||||
import cz.jzitnik.client.screens.scenes.Scene;
|
|
||||||
|
|
||||||
public class WinScene extends Scene {
|
|
||||||
public WinScene() {
|
|
||||||
super(new Screen[]{new WinScreen()}, new OnEndAction.Repeat());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,483 +0,0 @@
|
|||||||
package cz.jzitnik.client.game.setup.scenes.connect;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.TerminalSize;
|
|
||||||
import com.googlecode.lanterna.TextColor;
|
|
||||||
import com.googlecode.lanterna.graphics.TextGraphics;
|
|
||||||
import com.googlecode.lanterna.input.KeyType;
|
|
||||||
import com.googlecode.lanterna.screen.TerminalScreen;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.KeyboardPressEvent;
|
|
||||||
import cz.jzitnik.client.events.MouseAction;
|
|
||||||
import cz.jzitnik.client.events.SendSocketMessageEvent;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.screens.Screen;
|
|
||||||
import cz.jzitnik.client.screens.scenes.Scene;
|
|
||||||
import cz.jzitnik.client.socket.Client;
|
|
||||||
import cz.jzitnik.client.sound.SoundPlayer;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.ui.Inventory;
|
|
||||||
import cz.jzitnik.client.ui.pixels.AlphaPixel;
|
|
||||||
import cz.jzitnik.client.ui.pixels.Empty;
|
|
||||||
import cz.jzitnik.client.ui.utils.Input;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.client.utils.TextRenderer;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.connection.ConnectToAGame;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.creation.CreateGame;
|
|
||||||
import jakarta.websocket.DeploymentException;
|
|
||||||
import cz.jzitnik.client.ui.utils.Button;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class ServerChoose extends Scene {
|
|
||||||
public ServerChoose(DependencyManager dependencyManager) {
|
|
||||||
GameMenuAudioScreen gameMenuScreen = new GameMenuAudioScreen();
|
|
||||||
ServerSelector serverSelector = new ServerSelector();
|
|
||||||
|
|
||||||
super(new Screen[]{gameMenuScreen, serverSelector}, new OnEndAction.Repeat());
|
|
||||||
|
|
||||||
dependencyManager.inject(this);
|
|
||||||
dependencyManager.inject(serverSelector);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GameMenuAudioScreen extends Screen {
|
|
||||||
protected final SoundPlayer soundPlayer = new SoundPlayer();
|
|
||||||
protected boolean play = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
// No render here just basic audio playback
|
|
||||||
new Thread(() -> {
|
|
||||||
while (play) {
|
|
||||||
soundPlayer.playSound("audio/menu.ogg", 30, 100);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ServerSelector extends Screen {
|
|
||||||
private final StringBuilder ipBuffer = new StringBuilder();
|
|
||||||
private boolean connecting = false;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private TextRenderer textRenderer;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
private void renderInput(boolean refresh) {
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
Input input = new Input(ipBuffer.toString(), 18, 100);
|
|
||||||
var inputBuffer = input.render(textRenderer);
|
|
||||||
TerminalSize termSize = screen.getTerminalSize();
|
|
||||||
int renderPixelWidth = inputBuffer[0].length;
|
|
||||||
int renderPixelHeight = inputBuffer.length;
|
|
||||||
int renderCharWidth = renderPixelWidth;
|
|
||||||
int renderCharHeight = (renderPixelHeight + 1) / 2;
|
|
||||||
int startX = (termSize.getColumns() - renderCharWidth) / 2;
|
|
||||||
int startY = (termSize.getRows() - renderCharHeight) / 2;
|
|
||||||
|
|
||||||
for (int y = 0; y < inputBuffer.length; y += 2) {
|
|
||||||
for (int x = 0; x < inputBuffer[y].length; x++) {
|
|
||||||
AlphaPixel bottomPixel;
|
|
||||||
AlphaPixel topPixel = inputBuffer[y][x];
|
|
||||||
if (y + 1 < inputBuffer.length) {
|
|
||||||
bottomPixel = inputBuffer[y + 1][x];
|
|
||||||
} else {
|
|
||||||
bottomPixel = new Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int termX = startX + x;
|
|
||||||
int termY = startY + (y / 2);
|
|
||||||
|
|
||||||
tg.setBackgroundColor(topPixel instanceof Empty ? TextColor.ANSI.BLACK : topPixel.getColor());
|
|
||||||
tg.setForegroundColor(bottomPixel instanceof Empty ? TextColor.ANSI.BLACK : bottomPixel.getColor());
|
|
||||||
tg.setCharacter(termX, termY, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refresh) {
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.DELTA);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
screen.clear();
|
|
||||||
TerminalSize terminalSize = screen.getTerminalSize();
|
|
||||||
|
|
||||||
for (int y = 0; y < terminalSize.getRows(); y += 1) {
|
|
||||||
for (int x = 0; x < terminalSize.getColumns(); x++) {
|
|
||||||
tg.setBackgroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setForegroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setCharacter(x, y, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AlphaPixel[][] selectServer = textRenderer.renderText("Enter server IP", terminalSize.getColumns(), 20, Color.WHITE, 15f, true);
|
|
||||||
|
|
||||||
render(selectServer, 0, 10, tg);
|
|
||||||
|
|
||||||
renderInput(false);
|
|
||||||
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
if (connecting) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Enter) {
|
|
||||||
try {
|
|
||||||
connecting = true;
|
|
||||||
client.connect(ipBuffer.toString());
|
|
||||||
|
|
||||||
Screen screen = new ActionSelector();
|
|
||||||
dependencyManager.inject(screen);
|
|
||||||
gameState.setScreen(screen);
|
|
||||||
screen.fullRender();
|
|
||||||
} catch (DeploymentException | IOException e) {
|
|
||||||
connecting = false;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Backspace) {
|
|
||||||
if (ipBuffer.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipBuffer.deleteCharAt(ipBuffer.length() - 1);
|
|
||||||
renderInput(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Character && !event.getKeyStroke().isCtrlDown()) {
|
|
||||||
ipBuffer.append(event.getKeyStroke().getCharacter());
|
|
||||||
renderInput(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ActionSelector extends Screen {
|
|
||||||
@InjectDependency
|
|
||||||
private TextRenderer textRenderer;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
private int selectedIndex = -1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
screen.clear();
|
|
||||||
TerminalSize terminalSize = screen.getTerminalSize();
|
|
||||||
|
|
||||||
for (int y = 0; y < terminalSize.getRows(); y += 1) {
|
|
||||||
for (int x = 0; x < terminalSize.getColumns(); x++) {
|
|
||||||
tg.setBackgroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setForegroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setCharacter(x, y, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AlphaPixel[][] selectAction = textRenderer.renderText("Select action", terminalSize.getColumns(), 20, Color.WHITE, 15f, true);
|
|
||||||
|
|
||||||
render(selectAction, 0, 10, tg);
|
|
||||||
renderButtons();
|
|
||||||
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int BUTTON_HEIGHT = 20;
|
|
||||||
private static final int BUTTON_WIDTH = 200;
|
|
||||||
private static final int BUTTON_GAP = 10;
|
|
||||||
private static final int BUTTON_COUNT = 2;
|
|
||||||
private static final int BUTTONS_HEIGHT = BUTTON_HEIGHT * BUTTON_COUNT + (BUTTON_COUNT - 1) * BUTTON_GAP;
|
|
||||||
|
|
||||||
private void renderButtons() {
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize();
|
|
||||||
|
|
||||||
final int BUTTON_PAD_X = terminalSize.getColumns() / 2 - BUTTON_WIDTH / 2;
|
|
||||||
final int BUTTON_PAD_Y = terminalSize.getRows() - BUTTONS_HEIGHT / 2;
|
|
||||||
|
|
||||||
Button button = new Button(
|
|
||||||
Inventory.BORDER_COLOR,
|
|
||||||
Inventory.BACKGROUND_COLOR,
|
|
||||||
Inventory.BACKGROUND_COLOR_HOVERED,
|
|
||||||
Color.WHITE,
|
|
||||||
BUTTON_HEIGHT,
|
|
||||||
BUTTON_WIDTH,
|
|
||||||
1,
|
|
||||||
15f,
|
|
||||||
textRenderer
|
|
||||||
);
|
|
||||||
|
|
||||||
render(button.render("Create a world", selectedIndex == 0), BUTTON_PAD_X, BUTTON_PAD_Y, tg);
|
|
||||||
render(button.render("Connect to an existing world", selectedIndex == 1), BUTTON_PAD_X, BUTTON_PAD_Y + (BUTTON_HEIGHT + BUTTON_GAP), tg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize();
|
|
||||||
|
|
||||||
final int BUTTON_START_X = terminalSize.getColumns() / 2 - BUTTON_WIDTH / 2;
|
|
||||||
final int BUTTON_START_Y = terminalSize.getRows() - BUTTONS_HEIGHT / 2;
|
|
||||||
final int BUTTON_END_X = BUTTON_START_X + BUTTON_WIDTH;
|
|
||||||
final int BUTTON_END_Y = BUTTON_START_Y + BUTTONS_HEIGHT;
|
|
||||||
|
|
||||||
final int TERMINAL_X = event.getPosition().getColumn();
|
|
||||||
final int TERMINAL_Y = event.getPosition().getRow() * 2;
|
|
||||||
|
|
||||||
final int SINGLE_BUTTON_HEIGHT = BUTTON_HEIGHT + BUTTON_GAP;
|
|
||||||
|
|
||||||
int index = (TERMINAL_Y - BUTTON_START_Y) / SINGLE_BUTTON_HEIGHT;
|
|
||||||
int rest = (TERMINAL_Y - BUTTON_START_Y) % SINGLE_BUTTON_HEIGHT;
|
|
||||||
|
|
||||||
if (!(TERMINAL_X >= BUTTON_START_X && TERMINAL_Y >= BUTTON_START_Y && TERMINAL_X < BUTTON_END_X && TERMINAL_Y < BUTTON_END_Y) || rest > BUTTON_HEIGHT) {
|
|
||||||
if (selectedIndex != -1) {
|
|
||||||
selectedIndex = -1;
|
|
||||||
renderButtons();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.getActionType()) {
|
|
||||||
case MOVE -> {
|
|
||||||
selectedIndex = index;
|
|
||||||
renderButtons();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
case CLICK_RELEASE -> {
|
|
||||||
switch (index) {
|
|
||||||
case 0 -> eventManager.emitEvent(new SendSocketMessageEvent(new CreateGame()));
|
|
||||||
case 1 -> {
|
|
||||||
Screen screen = new ConnectWorld();
|
|
||||||
gameState.setScreen(screen);
|
|
||||||
screen.fullRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refresh() {
|
|
||||||
try {
|
|
||||||
terminalState.getTerminalScreen().refresh(com.googlecode.lanterna.screen.Screen.RefreshType.DELTA);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static final class ConnectWorld extends Screen {
|
|
||||||
private final StringBuilder passBuffer = new StringBuilder();
|
|
||||||
private boolean connecting = false;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private TextRenderer textRenderer;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
private void renderInput(boolean refresh) {
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
Input input = new Input(passBuffer.toString(), 18, 100);
|
|
||||||
var inputBuffer = input.render(textRenderer);
|
|
||||||
TerminalSize termSize = screen.getTerminalSize();
|
|
||||||
int renderPixelWidth = inputBuffer[0].length;
|
|
||||||
int renderPixelHeight = inputBuffer.length;
|
|
||||||
int renderCharWidth = renderPixelWidth;
|
|
||||||
int renderCharHeight = (renderPixelHeight + 1) / 2;
|
|
||||||
int startX = (termSize.getColumns() - renderCharWidth) / 2;
|
|
||||||
int startY = (termSize.getRows() - renderCharHeight) / 2;
|
|
||||||
|
|
||||||
for (int y = 0; y < inputBuffer.length; y += 2) {
|
|
||||||
for (int x = 0; x < inputBuffer[y].length; x++) {
|
|
||||||
AlphaPixel bottomPixel;
|
|
||||||
AlphaPixel topPixel = inputBuffer[y][x];
|
|
||||||
if (y + 1 < inputBuffer.length) {
|
|
||||||
bottomPixel = inputBuffer[y + 1][x];
|
|
||||||
} else {
|
|
||||||
bottomPixel = new Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int termX = startX + x;
|
|
||||||
int termY = startY + (y / 2);
|
|
||||||
|
|
||||||
tg.setBackgroundColor(topPixel instanceof Empty ? TextColor.ANSI.BLACK : topPixel.getColor());
|
|
||||||
tg.setForegroundColor(bottomPixel instanceof Empty ? TextColor.ANSI.BLACK : bottomPixel.getColor());
|
|
||||||
tg.setCharacter(termX, termY, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refresh) {
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.DELTA);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
var tg = terminalState.getTextGraphics();
|
|
||||||
screen.clear();
|
|
||||||
TerminalSize terminalSize = screen.getTerminalSize();
|
|
||||||
|
|
||||||
for (int y = 0; y < terminalSize.getRows(); y += 1) {
|
|
||||||
for (int x = 0; x < terminalSize.getColumns(); x++) {
|
|
||||||
tg.setBackgroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setForegroundColor(TextColor.ANSI.BLACK);
|
|
||||||
tg.setCharacter(x, y, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AlphaPixel[][] selectServer = textRenderer.renderText("Enter world password", terminalSize.getColumns(), 20, Color.WHITE, 15f, true);
|
|
||||||
|
|
||||||
render(selectServer, 0, 10, tg);
|
|
||||||
|
|
||||||
renderInput(false);
|
|
||||||
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
if (connecting) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Enter) {
|
|
||||||
connecting = true;
|
|
||||||
String pass = passBuffer.toString();
|
|
||||||
eventManager.emitEvent(new SendSocketMessageEvent(new ConnectToAGame(pass)));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Backspace) {
|
|
||||||
if (passBuffer.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
passBuffer.deleteCharAt(passBuffer.length() - 1);
|
|
||||||
renderInput(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKeyStroke().getKeyType() == KeyType.Character && !event.getKeyStroke().isCtrlDown()) {
|
|
||||||
passBuffer.append(event.getKeyStroke().getCharacter());
|
|
||||||
renderInput(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void render(AlphaPixel[][] buffer, int padX, int padY, TextGraphics tg) {
|
|
||||||
for (int y = 0; y < buffer.length; y += 2) {
|
|
||||||
for (int x = 0; x < buffer[y].length; x++) {
|
|
||||||
AlphaPixel topPixel = buffer[y][x];
|
|
||||||
|
|
||||||
AlphaPixel bottomPixel;
|
|
||||||
if (y + 1 < buffer.length) {
|
|
||||||
bottomPixel = buffer[y + 1][x];
|
|
||||||
} else {
|
|
||||||
bottomPixel = new Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int termX = padX + x;
|
|
||||||
int termY = padY / 2 + y / 2;
|
|
||||||
|
|
||||||
tg.setBackgroundColor(topPixel instanceof Empty ? TextColor.ANSI.BLACK : topPixel.getColor());
|
|
||||||
tg.setForegroundColor(bottomPixel instanceof Empty ? TextColor.ANSI.BLACK : bottomPixel.getColor());
|
|
||||||
tg.setCharacter(termX, termY, '▄');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package cz.jzitnik.client.screens;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.SGR;
|
|
||||||
import com.googlecode.lanterna.TextColor;
|
|
||||||
import com.googlecode.lanterna.graphics.TextGraphics;
|
|
||||||
import com.googlecode.lanterna.screen.TerminalScreen;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.KeyboardPressEvent;
|
|
||||||
import cz.jzitnik.client.events.MouseAction;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class DeathScreen extends Screen {
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
screen.clear();
|
|
||||||
TextGraphics tg = terminalState.getTextGraphics();
|
|
||||||
|
|
||||||
int termWidth = screen.getTerminalSize().getColumns();
|
|
||||||
int termHeight = screen.getTerminalSize().getRows();
|
|
||||||
|
|
||||||
String message = "GAME OVER";
|
|
||||||
tg.setForegroundColor(TextColor.ANSI.RED);
|
|
||||||
tg.enableModifiers(SGR.BOLD);
|
|
||||||
tg.putString((termWidth - message.length()) / 2, termHeight / 2, message);
|
|
||||||
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package cz.jzitnik.client.screens;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.SGR;
|
|
||||||
import com.googlecode.lanterna.TextColor;
|
|
||||||
import com.googlecode.lanterna.graphics.TextGraphics;
|
|
||||||
import com.googlecode.lanterna.screen.TerminalScreen;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.KeyboardPressEvent;
|
|
||||||
import cz.jzitnik.client.events.MouseAction;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class WinScreen extends Screen {
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fullRender() {
|
|
||||||
TerminalScreen screen = terminalState.getTerminalScreen();
|
|
||||||
screen.clear();
|
|
||||||
TextGraphics tg = terminalState.getTextGraphics();
|
|
||||||
|
|
||||||
int termWidth = screen.getTerminalSize().getColumns();
|
|
||||||
int termHeight = screen.getTerminalSize().getRows();
|
|
||||||
|
|
||||||
String message = "YOU WON!";
|
|
||||||
tg.setForegroundColor(TextColor.ANSI.GREEN);
|
|
||||||
tg.enableModifiers(SGR.BOLD);
|
|
||||||
tg.putString((termWidth - message.length()) / 2, termHeight / 2, message);
|
|
||||||
|
|
||||||
try {
|
|
||||||
screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMouseAction(MouseAction event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleKeyboardAction(KeyboardPressEvent event) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket;
|
|
||||||
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
|
|
||||||
public abstract class AbstractSocketEventHandler<T extends SocketMessage> {
|
|
||||||
public abstract void handle(T event);
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.Dependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
import jakarta.websocket.*;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Dependency
|
|
||||||
@ClientEndpoint
|
|
||||||
public class Client {
|
|
||||||
private Session session;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private SocketEventManager socketEventManager;
|
|
||||||
|
|
||||||
@OnOpen
|
|
||||||
public void onOpen(Session session) {
|
|
||||||
this.session = session;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnMessage
|
|
||||||
public void onMessage(ByteBuffer buffer) {
|
|
||||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer.array()))) {
|
|
||||||
SocketMessage message = (SocketMessage) ois.readObject();
|
|
||||||
socketEventManager.emitEvent(message);
|
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(SocketMessage message) throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(message);
|
|
||||||
oos.flush();
|
|
||||||
|
|
||||||
session.getBasicRemote().sendBinary(ByteBuffer.wrap(baos.toByteArray()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect(String ip) throws DeploymentException, IOException {
|
|
||||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
|
||||||
container.connectToServer(this, URI.create(String.format("ws://%s:8025/ws", ip)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.Dependency;
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectConfig;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.config.ThreadPoolConfig;
|
|
||||||
import cz.jzitnik.client.states.RunningState;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.common.socket.SocketMessage;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Dependency
|
|
||||||
public class SocketEventManager extends Thread {
|
|
||||||
private final DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
private ExecutorService eventExecutor;
|
|
||||||
private final HashMap<Class<? extends SocketMessage>, AbstractSocketEventHandler<?>> handlers = new HashMap<>();
|
|
||||||
private final BlockingQueue<SocketMessage> eventQueue = new LinkedBlockingQueue<>();
|
|
||||||
|
|
||||||
@InjectConfig
|
|
||||||
private ThreadPoolConfig threadPoolConfig;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private RunningState runningState;
|
|
||||||
|
|
||||||
public void emitEvent(SocketMessage event) {
|
|
||||||
eventQueue.add(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketEventManager(Reflections reflections, DependencyManager dependencyManager) {
|
|
||||||
this.dependencyManager = dependencyManager;
|
|
||||||
setDaemon(true);
|
|
||||||
|
|
||||||
var classes = reflections.getTypesAnnotatedWith(SocketEventHandler.class);
|
|
||||||
|
|
||||||
for (var clazz : classes) {
|
|
||||||
SocketEventHandler eventHandler = clazz.getAnnotation(SocketEventHandler.class);
|
|
||||||
try {
|
|
||||||
var instance = (AbstractSocketEventHandler<?>) clazz.getDeclaredConstructor().newInstance();
|
|
||||||
handlers.put(eventHandler.value(), instance);
|
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
|
|
||||||
NoSuchMethodException e) {
|
|
||||||
log.error("Failed to instantiate socket event handler: {}", clazz.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (Object instance : handlers.values()) {
|
|
||||||
dependencyManager.inject(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventExecutor = Executors.newFixedThreadPool(threadPoolConfig.eventThreadCount());
|
|
||||||
while (runningState.isRunning()) {
|
|
||||||
try {
|
|
||||||
SocketMessage event = eventQueue.take();
|
|
||||||
handleEvent(event);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// The game is shutting down.
|
|
||||||
eventExecutor.shutdownNow();
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventExecutor.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T extends SocketMessage> AbstractSocketEventHandler<T> getHandler(Class<T> type) {
|
|
||||||
return (AbstractSocketEventHandler<T>) handlers.get(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void handleEvent(SocketMessage event) {
|
|
||||||
eventExecutor.submit(() -> {
|
|
||||||
try {
|
|
||||||
AbstractSocketEventHandler<SocketMessage> handler = getHandler((Class<SocketMessage>) event.getClass());
|
|
||||||
handler.handle(event);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.TerminalResizeEvent;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.OtherPlayer;
|
|
||||||
import cz.jzitnik.client.game.Player;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.connection.ConnectToAGameResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(ConnectToAGameResponse.class)
|
|
||||||
public class ConnectGameHandler extends AbstractSocketEventHandler<ConnectToAGameResponse> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ConnectToAGameResponse event) {
|
|
||||||
if (!event.success()) {
|
|
||||||
log.debug("Error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gameState.setPlayer(new Player(event.playerCreation()));
|
|
||||||
gameState.getAllOtherPlayers().addAll(event.existingPlayers().stream().map(OtherPlayer::new).toList());
|
|
||||||
gameState.setScreen(null);
|
|
||||||
eventManager.emitEvent(new TerminalResizeEvent(terminalState.getTerminalScreen().getTerminalSize()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.TerminalResizeEvent;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.Player;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.creation.CreateGameResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(CreateGameResponse.class)
|
|
||||||
public class CreateGameHandler extends AbstractSocketEventHandler<CreateGameResponse> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(CreateGameResponse event) {
|
|
||||||
log.debug("Game code: {}", event.getGamePassword());
|
|
||||||
gameState.setPlayer(new Player(event.getOwnerPlayer()));
|
|
||||||
gameState.setScreen(null);
|
|
||||||
eventManager.emitEvent(new TerminalResizeEvent(terminalState.getTerminalScreen().getTerminalSize()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.setup.scenes.WinScene;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.GameWin;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(GameWin.class)
|
|
||||||
public class GameWinHandler extends AbstractSocketEventHandler<GameWin> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler roomTaskScheduler;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(GameWin event) {
|
|
||||||
log.debug("Game won!");
|
|
||||||
roomTaskScheduler.finalShutdown();
|
|
||||||
WinScene winScene = new WinScene();
|
|
||||||
gameState.setScreen(winScene);
|
|
||||||
try {
|
|
||||||
Thread.sleep(500);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
winScene.fullRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.GameRoom;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.items.GameItem;
|
|
||||||
import cz.jzitnik.client.game.objects.Chest;
|
|
||||||
import cz.jzitnik.client.game.objects.GameObject;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.common.socket.messages.items.ItemTookFromChest;
|
|
||||||
|
|
||||||
@SocketEventHandler(ItemTookFromChest.class)
|
|
||||||
public class ItemTookFromChestHandler extends AbstractSocketEventHandler<ItemTookFromChest> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ItemTookFromChest event) {
|
|
||||||
for (GameRoom room : gameState.getAllRooms()) {
|
|
||||||
if (!room.getId().equals(event.roomId())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (GameObject object : room.getObjects()) {
|
|
||||||
if (object instanceof Chest chest) {
|
|
||||||
var items = chest.getItems();
|
|
||||||
|
|
||||||
for (GameItem item : items) {
|
|
||||||
if (item.getId() != event.id()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
items.remove(item);
|
|
||||||
chest.handleItemRemoval(item);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.events.FullRoomDraw;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.OtherPlayer;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.room.MovePlayerRoomResponse;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@SocketEventHandler(MovePlayerRoomResponse.class)
|
|
||||||
public class MovePlayerRoomResponseHandler extends AbstractSocketEventHandler<MovePlayerRoomResponse> {
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(MovePlayerRoomResponse event) {
|
|
||||||
Set<Integer> ids = event.getIds();
|
|
||||||
|
|
||||||
for (OtherPlayer player : gameState.getAllOtherPlayers()) {
|
|
||||||
player.setVisible(ids.contains(player.getId()));
|
|
||||||
var playerRegistryOptional = event.getById(player.getId());
|
|
||||||
if (player.isVisible() && playerRegistryOptional.isPresent()) {
|
|
||||||
player.getPlayerCords().updateCords(playerRegistryOptional.get().cords());
|
|
||||||
player.setPlayerRotation(playerRegistryOptional.get().playerRotation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventManager.emitEvent(new FullRoomDraw());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.TerminalPosition;
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectConfig;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.config.Debugging;
|
|
||||||
import cz.jzitnik.client.events.MouseMoveEvent;
|
|
||||||
import cz.jzitnik.client.events.RerenderScreen;
|
|
||||||
import cz.jzitnik.client.game.GameRoom;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.OtherPlayer;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.states.ScreenBuffer;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.ui.Stats;
|
|
||||||
import cz.jzitnik.client.utils.RerenderUtils;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerArrivalChange;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(PlayerArrivalChange.class)
|
|
||||||
public class PlayerArrivalChangeHandler extends AbstractSocketEventHandler<PlayerArrivalChange> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ResourceManager resourceManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private ScreenBuffer screenBuffer;
|
|
||||||
|
|
||||||
@InjectConfig
|
|
||||||
private Debugging debugging;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(PlayerArrivalChange event) {
|
|
||||||
log.debug("Player appear change: {}", event.id());
|
|
||||||
OtherPlayer otherPlayer = gameState.getAllOtherPlayers().stream().filter(otherPlayer1 -> otherPlayer1.getId() == event.id()).findFirst().get();
|
|
||||||
otherPlayer.setVisible(event.arrived());
|
|
||||||
otherPlayer.getPlayerCords().updateCords(event.playerCords());
|
|
||||||
otherPlayer.setPlayerRotation(event.playerRotation());
|
|
||||||
|
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
|
||||||
BufferedImage playerTexture = otherPlayer.getTexture(resourceManager);
|
|
||||||
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
|
||||||
|
|
||||||
int forStartX = event.playerCords().getX();
|
|
||||||
int forStartY = event.playerCords().getY();
|
|
||||||
int forEndX = forStartX + playerTexture.getWidth();
|
|
||||||
int forEndY = forStartY + playerTexture.getHeight();
|
|
||||||
|
|
||||||
var start = RerenderUtils.getStart(room, terminalState.getTerminalScreen().getTerminalSize());
|
|
||||||
int startX = start.getX();
|
|
||||||
int startY = start.getY();
|
|
||||||
|
|
||||||
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, currentRoom, room, gameState.getPlayer(), screenBuffer, resourceManager, debugging, gameState.getOtherPlayers());
|
|
||||||
|
|
||||||
eventManager.emitEvent(new Event[]{
|
|
||||||
new MouseMoveEvent(null),
|
|
||||||
new RerenderScreen(
|
|
||||||
new RerenderScreen.ScreenPart[]{
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
|
||||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
|
||||||
),
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
new TerminalPosition(Stats.OFFSET_X, Stats.OFFSET_X),
|
|
||||||
new TerminalPosition(Stats.OFFSET_X + Stats.WIDTH, Stats.OFFSET_Y + Stats.HEIGHT)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.setup.scenes.DeathScene;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.utils.DependencyManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.game.PlayerDeath;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(PlayerDeath.class)
|
|
||||||
public class PlayerDeathHandler extends AbstractSocketEventHandler<PlayerDeath> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private DependencyManager dependencyManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler roomTaskScheduler;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(PlayerDeath event) {
|
|
||||||
log.debug("Player death: {}", event.playerId());
|
|
||||||
roomTaskScheduler.finalShutdown();
|
|
||||||
DeathScene deathScene = new DeathScene();
|
|
||||||
dependencyManager.inject(deathScene);
|
|
||||||
gameState.setScreen(deathScene);
|
|
||||||
deathScene.fullRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerDisconnected;
|
|
||||||
|
|
||||||
@SocketEventHandler(PlayerDisconnected.class)
|
|
||||||
public class PlayerDisconnectedHandler extends AbstractSocketEventHandler<PlayerDisconnected> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(PlayerDisconnected event) {
|
|
||||||
gameState.getAllOtherPlayers().removeIf(player -> player.getId() == event.playerId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.OtherPlayer;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerJoined;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(PlayerJoined.class)
|
|
||||||
public class PlayerJoinedHandler extends AbstractSocketEventHandler<PlayerJoined> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(PlayerJoined event) {
|
|
||||||
log.debug("Player joined: {}", event.playerCreation().getId());
|
|
||||||
gameState.getAllOtherPlayers().add(new OtherPlayer(event.playerCreation()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package cz.jzitnik.client.socket.events;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.TerminalPosition;
|
|
||||||
import cz.jzitnik.client.annotations.SocketEventHandler;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectConfig;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectDependency;
|
|
||||||
import cz.jzitnik.client.annotations.injectors.InjectState;
|
|
||||||
import cz.jzitnik.client.config.Debugging;
|
|
||||||
import cz.jzitnik.client.events.MouseMoveEvent;
|
|
||||||
import cz.jzitnik.client.events.RerenderScreen;
|
|
||||||
import cz.jzitnik.client.game.GameRoom;
|
|
||||||
import cz.jzitnik.client.game.GameState;
|
|
||||||
import cz.jzitnik.client.game.OtherPlayer;
|
|
||||||
import cz.jzitnik.client.game.ResourceManager;
|
|
||||||
import cz.jzitnik.client.socket.AbstractSocketEventHandler;
|
|
||||||
import cz.jzitnik.client.states.ScreenBuffer;
|
|
||||||
import cz.jzitnik.client.states.TerminalState;
|
|
||||||
import cz.jzitnik.client.ui.Stats;
|
|
||||||
import cz.jzitnik.client.utils.RerenderUtils;
|
|
||||||
import cz.jzitnik.client.utils.events.Event;
|
|
||||||
import cz.jzitnik.client.utils.events.EventManager;
|
|
||||||
import cz.jzitnik.common.socket.messages.player.PlayerMovedInUrRoom;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@SocketEventHandler(PlayerMovedInUrRoom.class)
|
|
||||||
public class PlayerMovedInUrRoomHandler extends AbstractSocketEventHandler<PlayerMovedInUrRoom> {
|
|
||||||
@InjectState
|
|
||||||
private GameState gameState;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private EventManager eventManager;
|
|
||||||
|
|
||||||
@InjectDependency
|
|
||||||
private ResourceManager resourceManager;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private ScreenBuffer screenBuffer;
|
|
||||||
|
|
||||||
@InjectConfig
|
|
||||||
private Debugging debugging;
|
|
||||||
|
|
||||||
@InjectState
|
|
||||||
private TerminalState terminalState;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(PlayerMovedInUrRoom event) {
|
|
||||||
log.debug("Player moved: {}", event.getPlayerId());
|
|
||||||
OtherPlayer otherPlayer = gameState.getAllOtherPlayers().stream().filter(otherPlayer1 -> otherPlayer1.getId() == event.getPlayerId()).findFirst().get();
|
|
||||||
otherPlayer.setPlayerRotation(event.getPlayerRotation());
|
|
||||||
|
|
||||||
var oldCords = otherPlayer.getPlayerCords();
|
|
||||||
var newCords = event.getCords();
|
|
||||||
|
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
|
||||||
BufferedImage playerTexture = otherPlayer.getTexture(resourceManager);
|
|
||||||
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
|
||||||
int originalPlayerX = oldCords.getX();
|
|
||||||
int originalPlayerY = oldCords.getY();
|
|
||||||
int newPlayerX = newCords.getX();
|
|
||||||
int newPlayerY = newCords.getY();
|
|
||||||
|
|
||||||
int forStartX = Math.min(originalPlayerX, newPlayerX);
|
|
||||||
int forStartY = Math.min(originalPlayerY, newPlayerY);
|
|
||||||
int forEndX = Math.max(originalPlayerX, newPlayerX) + playerTexture.getWidth();
|
|
||||||
int forEndY = Math.max(originalPlayerY, newPlayerY) + playerTexture.getHeight();
|
|
||||||
|
|
||||||
var start = RerenderUtils.getStart(room, terminalState.getTerminalScreen().getTerminalSize());
|
|
||||||
int startX = start.getX();
|
|
||||||
int startY = start.getY();
|
|
||||||
|
|
||||||
otherPlayer.getPlayerCords().updateCords(newCords);
|
|
||||||
|
|
||||||
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, currentRoom, room, gameState.getPlayer(), screenBuffer, resourceManager, debugging, gameState.getOtherPlayers());
|
|
||||||
|
|
||||||
eventManager.emitEvent(new Event[]{
|
|
||||||
new MouseMoveEvent(null),
|
|
||||||
new RerenderScreen(
|
|
||||||
new RerenderScreen.ScreenPart[]{
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
|
||||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
|
||||||
),
|
|
||||||
new RerenderScreen.ScreenPart(
|
|
||||||
new TerminalPosition(Stats.OFFSET_X, Stats.OFFSET_X),
|
|
||||||
new TerminalPosition(Stats.OFFSET_X + Stats.WIDTH, Stats.OFFSET_Y + Stats.HEIGHT)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user