Compare commits

..

23 Commits

Author SHA1 Message Date
f2b6200355 docs: Add controls 2026-02-22 22:00:26 +01:00
e15d4ec874 chore: Late something 2026-02-22 21:46:12 +01:00
dac6d666b2 chore: Minor changes 2026-02-22 20:59:20 +01:00
3dd2c389b8 feat: Multiplayer 2026-02-22 20:37:05 +01:00
f7d878f430 feat: End 2026-02-22 20:24:31 +01:00
32f8521951 feat: Death 2026-02-21 13:46:27 +01:00
f8f150cdf0 feat: Give item on dialog 2026-02-18 10:59:51 +01:00
8935349f92 feat: Answer requirements 2026-02-18 09:13:00 +01:00
a8ce7b8ed1 feat: Some game additions 2026-02-11 21:37:01 +01:00
6559cbe4c7 feat: Requirements for game 2026-02-08 18:03:08 +01:00
35918ac0ad feat: Make Dialog serializable 2026-02-08 13:25:37 +01:00
5366162f43 feat: Multiplayer (#3)
Reviewed-on: https://gitea.local.jzitnik.dev/jzitnik/game/pulls/3
Co-authored-by: jzitnik-dev <email@jzitnik.dev>
Co-committed-by: jzitnik-dev <email@jzitnik.dev>
2026-02-04 11:40:15 +01:00
69fae66635 chore: Game 2026-02-04 11:40:14 +01:00
33227ff91f chore: Updated dependencies 2026-02-04 11:40:14 +01:00
145ee0cd80 refactor: Config in files 2026-02-04 11:40:14 +01:00
c5fb45cabc refactor: Load a game setup from a yaml file 2026-02-04 11:40:14 +01:00
97c8f83e2b refactor: Reworked collision system 2026-02-04 11:40:14 +01:00
cb5dbaeb44 feat: Dialog running code and changeable tasks 2026-02-04 11:40:13 +01:00
a52fa7b8be refactor(events): Small event manager refactoring 2026-02-04 11:40:13 +01:00
a6cc33bbac feat: Show icons in stats 2026-02-04 11:40:13 +01:00
40eb53429c feat: Dialog answering 2026-02-04 11:40:13 +01:00
8b28539ab4 feat: Implemented text rendering 2026-02-04 11:40:12 +01:00
72c8cefd48 chore: Started implementing dialog 2026-02-04 11:40:05 +01:00
315 changed files with 6242 additions and 2441 deletions

41
.gitignore vendored
View File

@@ -1,42 +1 @@
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 Normal file
View File

@@ -0,0 +1,14 @@
<?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 Normal file
View File

@@ -0,0 +1,41 @@
<?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
View File

@@ -1,6 +1,12 @@
<?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 Normal file
View File

@@ -0,0 +1,25 @@
<?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
View File

@@ -1,17 +1,5 @@
<?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">
@@ -20,7 +8,5 @@
</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 Normal file
View File

@@ -0,0 +1,37 @@
# 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 Normal file
View File

@@ -0,0 +1,39 @@
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 Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

7
common/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?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 Normal file
View File

@@ -0,0 +1,14 @@
<?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 Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

63
common/pom.xml Normal file
View File

@@ -0,0 +1,63 @@
<?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>

View File

@@ -0,0 +1,5 @@
package cz.jzitnik.common;
public class Config {
public static final int WORLD_PASSWORD_LENGTH = 5;
}

View File

@@ -0,0 +1,77 @@
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);
}
}

View File

@@ -0,0 +1,41 @@
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();
}
}

View File

@@ -0,0 +1,27 @@
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;
}
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket;
import java.io.Serializable;
public interface SocketMessage extends Serializable {
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages;
import cz.jzitnik.common.socket.SocketMessage;
public class Test implements SocketMessage {
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages.game;
import cz.jzitnik.common.socket.SocketMessage;
public record GameWin() implements SocketMessage {
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages.game;
import cz.jzitnik.common.socket.SocketMessage;
public record PlayerDeath(int playerId) implements SocketMessage {
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages.game.connection;
import cz.jzitnik.common.socket.SocketMessage;
public record ConnectToAGame(String gamePass) implements SocketMessage {
}

View File

@@ -0,0 +1,25 @@
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;
}
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages.game.creation;
import cz.jzitnik.common.socket.SocketMessage;
public class CreateGame implements SocketMessage {
}

View File

@@ -0,0 +1,13 @@
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;
}

View File

@@ -0,0 +1,9 @@
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 {
}

View File

@@ -0,0 +1,8 @@
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 {
}

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.common.socket.messages.player;
import cz.jzitnik.common.socket.SocketMessage;
public record PlayerDisconnected(int playerId) implements SocketMessage {
}

View File

@@ -0,0 +1,7 @@
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 {
}

View File

@@ -0,0 +1,7 @@
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 {
}

View File

@@ -0,0 +1,14 @@
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;
}

View File

@@ -0,0 +1,5 @@
package cz.jzitnik.common.socket.messages.player;
public enum PlayerRotation {
FRONT, BACK, LEFT, RIGHT
}

View File

@@ -0,0 +1,8 @@
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 {
}

View File

@@ -0,0 +1,22 @@
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 Normal file
View File

@@ -0,0 +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

3
game/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

13
game/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?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 Normal file
View File

@@ -0,0 +1,12 @@
<?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 Normal file
View File

@@ -0,0 +1,6 @@
<?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 Normal file
View File

@@ -0,0 +1,190 @@
<?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>

View File

@@ -1,18 +1,18 @@
package cz.jzitnik; package cz.jzitnik.client;
import com.googlecode.lanterna.input.KeyStroke; import com.googlecode.lanterna.input.KeyStroke;
import com.googlecode.lanterna.screen.TerminalScreen; import com.googlecode.lanterna.screen.TerminalScreen;
import com.googlecode.lanterna.terminal.DefaultTerminalFactory; import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.terminal.MouseCaptureMode; import com.googlecode.lanterna.terminal.MouseCaptureMode;
import cz.jzitnik.annotations.Dependency; import cz.jzitnik.client.annotations.Dependency;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.KeyboardPressEvent; import cz.jzitnik.client.events.KeyboardPressEvent;
import cz.jzitnik.events.MouseAction; import cz.jzitnik.client.events.MouseAction;
import cz.jzitnik.events.TerminalResizeEvent; import cz.jzitnik.client.events.TerminalResizeEvent;
import cz.jzitnik.states.RunningState; import cz.jzitnik.client.states.RunningState;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.utils.events.EventManager; import cz.jzitnik.client.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.IOException; import java.io.IOException;
@@ -31,8 +31,7 @@ public class Cli implements Runnable {
@Override @Override
public void run() { public void run() {
eventManager.start(); // Start event manager thread // Start event manager thread
try (TerminalScreen terminal = new DefaultTerminalFactory() try (TerminalScreen terminal = new DefaultTerminalFactory()
.setMouseCaptureMode(MouseCaptureMode.CLICK_RELEASE_DRAG_MOVE) .setMouseCaptureMode(MouseCaptureMode.CLICK_RELEASE_DRAG_MOVE)
.createScreen()) { .createScreen()) {

View File

@@ -0,0 +1,49 @@
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();
}
}

View File

@@ -0,0 +1,11 @@
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();
}
}

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -8,4 +8,5 @@ import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
public @interface Config { public @interface Config {
String value();
} }

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,6 +1,6 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -0,0 +1,14 @@
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();
}

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations; package cz.jzitnik.client.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.injectors; package cz.jzitnik.client.annotations.injectors;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.injectors; package cz.jzitnik.client.annotations.injectors;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.injectors; package cz.jzitnik.client.annotations.injectors;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
import com.googlecode.lanterna.input.KeyType; import com.googlecode.lanterna.input.KeyType;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
public enum MouseHandlerType { public enum MouseHandlerType {
CLICK, CLICK,

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.annotations.ui; package cz.jzitnik.client.annotations.ui;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;

View File

@@ -0,0 +1,15 @@
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;
}
}

View File

@@ -0,0 +1,19 @@
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;
}
}

View File

@@ -0,0 +1,15 @@
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;
}
}

View File

@@ -0,0 +1,36 @@
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;
}
}

View File

@@ -0,0 +1,17 @@
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;
}
}

View File

@@ -0,0 +1,7 @@
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 {
}

View File

@@ -1,6 +1,6 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
/** Custom event without any handler **/ /** Custom event without any handler **/
public class ExitEvent implements Event { public class ExitEvent implements Event {

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.client.events;
import cz.jzitnik.client.utils.events.Event;
public class FullRedrawEvent implements Event {
}

View File

@@ -1,7 +1,6 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.client.events;
import cz.jzitnik.client.utils.events.Event;
public class InventoryRerender implements Event {
}

View File

@@ -1,7 +1,7 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import com.googlecode.lanterna.input.KeyStroke; import com.googlecode.lanterna.input.KeyStroke;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,8 +1,8 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.input.MouseActionType; import com.googlecode.lanterna.input.MouseActionType;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
public class MouseAction extends com.googlecode.lanterna.input.MouseAction implements Event { public class MouseAction extends com.googlecode.lanterna.input.MouseAction implements Event {
public MouseAction(MouseActionType actionType, int button, TerminalPosition position) { public MouseAction(MouseActionType actionType, int button, TerminalPosition position) {

View File

@@ -1,6 +1,6 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,7 +1,7 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import com.googlecode.lanterna.input.KeyStroke; import com.googlecode.lanterna.input.KeyStroke;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.client.events;
import cz.jzitnik.client.utils.events.Event;
public class RenderStats implements Event {
}

View File

@@ -1,6 +1,6 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,13 +1,11 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TerminalSize;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import java.awt.*;
public record RerenderScreen(ScreenPart[] parts) implements Event { public record RerenderScreen(ScreenPart[] parts) implements Event {
public RerenderScreen(ScreenPart part) { public RerenderScreen(ScreenPart part) {
this(new ScreenPart[]{part}); this(new ScreenPart[]{part});

View File

@@ -0,0 +1,7 @@
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 {
}

View File

@@ -0,0 +1,7 @@
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 {
}

View File

@@ -1,7 +1,7 @@
package cz.jzitnik.events; package cz.jzitnik.client.events;
import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TerminalSize;
import cz.jzitnik.utils.events.Event; import cz.jzitnik.client.utils.events.Event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -0,0 +1,6 @@
package cz.jzitnik.client.events;
import cz.jzitnik.client.utils.events.Event;
public class TerminalTooSmallEvent implements Event {
}

View File

@@ -1,20 +1,19 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TextColor; import com.googlecode.lanterna.TextColor;
import com.googlecode.lanterna.graphics.TextGraphics; import com.googlecode.lanterna.graphics.TextGraphics;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.game.Constants; import cz.jzitnik.client.game.Constants;
import cz.jzitnik.states.RenderState; import cz.jzitnik.client.states.RenderState;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.ui.pixels.AlphaPixel; import cz.jzitnik.client.ui.pixels.AlphaPixel;
import cz.jzitnik.ui.pixels.ColoredPixel; import cz.jzitnik.client.ui.pixels.ColoredPixel;
import cz.jzitnik.ui.pixels.Empty; import cz.jzitnik.client.ui.pixels.Empty;
import cz.jzitnik.ui.pixels.Pixel; import cz.jzitnik.client.ui.pixels.Pixel;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.IOException; import java.io.IOException;
@@ -31,10 +30,6 @@ public class CliHandler extends AbstractEventHandler<RerenderScreen> {
@InjectState @InjectState
private RenderState renderState; private RenderState renderState;
public CliHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(RerenderScreen event) { public void handle(RerenderScreen event) {
if (renderState.isTerminalTooSmall()) { if (renderState.isTerminalTooSmall()) {

View File

@@ -0,0 +1,283 @@
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();
}
}
}
}

View File

@@ -1,22 +1,17 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.events.DroppedItemRerender; import cz.jzitnik.client.events.DroppedItemRerender;
import cz.jzitnik.events.RerenderPart; import cz.jzitnik.client.events.RerenderPart;
import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.common.models.coordinates.RoomCords;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@EventHandler(DroppedItemRerender.class) @EventHandler(DroppedItemRerender.class)
public class DroppedItemRerenderHandler extends AbstractEventHandler<DroppedItemRerender> { public class DroppedItemRerenderHandler extends AbstractEventHandler<DroppedItemRerender> {
public DroppedItemRerenderHandler(DependencyManager dm) {
super(dm);
}
@InjectDependency @InjectDependency
private EventManager eventManager; private EventManager eventManager;

View File

@@ -0,0 +1,35 @@
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
}
}

View File

@@ -1,15 +1,14 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.screen.Screen; import com.googlecode.lanterna.screen.Screen;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.FullRedrawEvent; import cz.jzitnik.client.events.FullRedrawEvent;
import cz.jzitnik.events.FullRoomDraw; import cz.jzitnik.client.events.FullRoomDraw;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
import java.io.IOException; import java.io.IOException;
@@ -21,10 +20,6 @@ public class FullRedrawEventHandler extends AbstractEventHandler<FullRedrawEvent
@InjectState @InjectState
private TerminalState terminalState; private TerminalState terminalState;
public FullRedrawEventHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(FullRedrawEvent event) { public void handle(FullRedrawEvent event) {
terminalState.getTerminalScreen().clear(); terminalState.getTerminalScreen().clear();

View File

@@ -1,32 +1,28 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.screen.TerminalScreen; import com.googlecode.lanterna.screen.TerminalScreen;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.client.annotations.injectors.InjectConfig;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.config.Debugging; import cz.jzitnik.client.config.Debugging;
import cz.jzitnik.events.FullRoomDraw; import cz.jzitnik.client.events.FullRoomDraw;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.events.TerminalTooSmallEvent; import cz.jzitnik.client.events.TerminalTooSmallEvent;
import cz.jzitnik.game.GameRoom; import cz.jzitnik.client.game.GameRoom;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.game.Player; import cz.jzitnik.client.game.Player;
import cz.jzitnik.game.ResourceManager; import cz.jzitnik.client.game.ResourceManager;
import cz.jzitnik.states.RenderState; import cz.jzitnik.client.states.RenderState;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.ui.Inventory; import cz.jzitnik.client.utils.GlobalIOHandlerRepository;
import cz.jzitnik.ui.Stats; import cz.jzitnik.client.utils.RerenderUtils;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.GlobalIOHandlerRepository; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler;
import cz.jzitnik.utils.UIRoomClickHandlerRepository;
import cz.jzitnik.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.EventManager;
import cz.jzitnik.utils.roomtasks.RoomTaskScheduler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -59,10 +55,6 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
@InjectDependency @InjectDependency
private GlobalIOHandlerRepository globalIOHandlerRepository; private GlobalIOHandlerRepository globalIOHandlerRepository;
public FullRoomDrawHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(FullRoomDraw event) { public void handle(FullRoomDraw event) {
try { try {
@@ -83,7 +75,7 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
int startX = start.getX(); int startX = start.getX();
int startY = start.getY(); int startY = start.getY();
RerenderUtils.rerenderPart(0, width - 1, 0, height - 1, startX, startY, currentRoom, room, player, playerTexture, screenBuffer, resourceManager, debugging); RerenderUtils.rerenderPart(0, width - 1, 0, height - 1, startX, startY, currentRoom, room, player, screenBuffer, resourceManager, debugging, gameState.getOtherPlayers());
if (event.isFullRerender()) { if (event.isFullRerender()) {
globalIOHandlerRepository.renderAll(); globalIOHandlerRepository.renderAll();
} }
@@ -96,9 +88,7 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
if (renderState.isFirstRender() || event.isFullRerender()) { if (renderState.isFirstRender() || event.isFullRerender()) {
eventManager.emitEvent(RerenderScreen.full(terminalSize)); eventManager.emitEvent(RerenderScreen.full(terminalSize));
renderState.setFirstRender(false); renderState.setFirstRender(false);
scheduler.schedule(() -> { scheduler.schedule(() -> roomTaskScheduler.setupNewSchedulers(currentRoom), 200, TimeUnit.MILLISECONDS);
roomTaskScheduler.setupNewSchedulers(currentRoom);
}, 200, TimeUnit.MILLISECONDS);
} else { } else {
eventManager.emitEvent(new RerenderScreen(partsToRerender.toArray(RerenderScreen.ScreenPart[]::new))); eventManager.emitEvent(new RerenderScreen(partsToRerender.toArray(RerenderScreen.ScreenPart[]::new)));
} }

View File

@@ -1,14 +1,13 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.events.InventoryRerender; import cz.jzitnik.client.events.InventoryRerender;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.ui.Inventory; import cz.jzitnik.client.ui.Inventory;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
@EventHandler(InventoryRerender.class) @EventHandler(InventoryRerender.class)
public class InventoryRerenderHandler extends AbstractEventHandler<InventoryRerender> { public class InventoryRerenderHandler extends AbstractEventHandler<InventoryRerender> {
@@ -18,10 +17,6 @@ public class InventoryRerenderHandler extends AbstractEventHandler<InventoryRere
@InjectDependency @InjectDependency
private Inventory inventory; private Inventory inventory;
public InventoryRerenderHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(InventoryRerender event) { public void handle(InventoryRerender event) {
inventory.renderInventoryRerender(); inventory.renderInventoryRerender();

View File

@@ -1,20 +1,15 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.*; import cz.jzitnik.client.events.KeyboardPressEvent;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.GlobalIOHandlerRepository;
import cz.jzitnik.utils.GlobalIOHandlerRepository; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler;
@EventHandler(KeyboardPressEvent.class) @EventHandler(KeyboardPressEvent.class)
public class KeyboardPressEventHandler extends AbstractEventHandler<KeyboardPressEvent> { public class KeyboardPressEventHandler extends AbstractEventHandler<KeyboardPressEvent> {
public KeyboardPressEventHandler(DependencyManager dm) {
super(dm);
}
@InjectState @InjectState
private GameState gameState; private GameState gameState;

View File

@@ -1,29 +1,25 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.client.annotations.injectors.InjectConfig;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.config.PlayerConfig; import cz.jzitnik.client.config.PlayerConfig;
import cz.jzitnik.events.MouseAction; import cz.jzitnik.client.events.MouseAction;
import cz.jzitnik.events.MouseMoveEvent; import cz.jzitnik.client.events.MouseMoveEvent;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.game.utils.Selectable; import cz.jzitnik.client.game.utils.Selectable;
import cz.jzitnik.states.RenderState; import cz.jzitnik.client.states.RenderState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.DependencyManager;
import cz.jzitnik.utils.UIRoomClickHandlerRepository; import cz.jzitnik.client.utils.UIRoomClickHandlerRepository;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.EventManager; import cz.jzitnik.client.utils.events.EventManager;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
@EventHandler(MouseAction.class) @EventHandler(MouseAction.class)
public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> { public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> {
public MouseActionEventHandler(DependencyManager dm) {
super(dm);
}
@InjectDependency @InjectDependency
private EventManager eventManager; private EventManager eventManager;
@@ -39,6 +35,9 @@ public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> {
@InjectConfig @InjectConfig
private PlayerConfig playerConfig; private PlayerConfig playerConfig;
@InjectDependency
private DependencyManager dependencyManager;
@Override @Override
public void handle(MouseAction event) { public void handle(MouseAction event) {
if (gameState.getScreen() != null) { if (gameState.getScreen() != null) {
@@ -74,10 +73,10 @@ public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> {
Optional<? extends Selectable> object = combined.filter(Selectable::isSelected).findFirst(); Optional<? extends Selectable> object = combined.filter(Selectable::isSelected).findFirst();
gameState.getPlayer().swing(playerConfig.getSwingTimeMs()); gameState.getPlayer().swing(playerConfig.swingTimeMs());
object.ifPresent(selectable -> { object.ifPresent(selectable -> {
dm.inject(selectable); dependencyManager.inject(selectable);
selectable.interact(); selectable.interact();
}); });
} }

View File

@@ -1,28 +1,27 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.input.MouseActionType; import com.googlecode.lanterna.input.MouseActionType;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.client.annotations.injectors.InjectConfig;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.config.Debugging; import cz.jzitnik.client.config.Debugging;
import cz.jzitnik.config.PlayerConfig; import cz.jzitnik.client.config.PlayerConfig;
import cz.jzitnik.events.MouseAction; import cz.jzitnik.client.events.MouseAction;
import cz.jzitnik.events.MouseMoveEvent; import cz.jzitnik.client.events.MouseMoveEvent;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.game.GameRoom; import cz.jzitnik.client.game.GameRoom;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.game.Player; import cz.jzitnik.client.game.Player;
import cz.jzitnik.game.ResourceManager; import cz.jzitnik.client.game.ResourceManager;
import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.common.models.coordinates.RoomCords;
import cz.jzitnik.game.utils.Selectable; import cz.jzitnik.client.game.utils.Selectable;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.RerenderUtils;
import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -36,10 +35,6 @@ import java.util.stream.Stream;
@Slf4j @Slf4j
@EventHandler(MouseMoveEvent.class) @EventHandler(MouseMoveEvent.class)
public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent> { public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent> {
public MouseMoveEventHandler(DependencyManager dm) {
super(dm);
}
private MouseMoveEvent lastEvent = new MouseMoveEvent(new MouseAction(MouseActionType.MOVE, 1, new TerminalPosition(0, 0))); private MouseMoveEvent lastEvent = new MouseMoveEvent(new MouseAction(MouseActionType.MOVE, 1, new TerminalPosition(0, 0)));
@InjectState @InjectState
@@ -138,7 +133,7 @@ public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent>
objXEnd, objYEnd objXEnd, objYEnd
); );
if (distance > playerConfig.getPlayerReach()) { if (distance > playerConfig.playerReach()) {
return false; return false;
} }
@@ -182,10 +177,10 @@ public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent>
currentRoom, currentRoom,
room, room,
player, player,
playerTexture,
screenBuffer, screenBuffer,
resourceManager, resourceManager,
debugging debugging,
gameState.getOtherPlayers()
); );
parts.add(new RerenderScreen.ScreenPart( parts.add(new RerenderScreen.ScreenPart(

View File

@@ -1,33 +1,27 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import com.googlecode.lanterna.input.KeyStroke; import com.googlecode.lanterna.input.KeyStroke;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.client.annotations.injectors.InjectConfig;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.config.Debugging; import cz.jzitnik.client.config.Debugging;
import cz.jzitnik.config.Logging; import cz.jzitnik.client.config.PlayerConfig;
import cz.jzitnik.config.PlayerConfig; import cz.jzitnik.client.events.*;
import cz.jzitnik.events.MouseMoveEvent; import cz.jzitnik.client.game.*;
import cz.jzitnik.events.PlayerMoveEvent; import cz.jzitnik.common.models.coordinates.RoomCords;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.states.RenderState;
import cz.jzitnik.events.RoomChangeEvent; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.game.GameRoom; import cz.jzitnik.client.states.PlayerMovementState;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.game.Player; import cz.jzitnik.client.ui.Stats;
import cz.jzitnik.game.ResourceManager; import cz.jzitnik.client.utils.RerenderUtils;
import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.states.RenderState; import cz.jzitnik.client.utils.events.Event;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.states.PlayerMovementState; import cz.jzitnik.common.socket.messages.player.PlayerMove;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.common.socket.messages.player.PlayerRotation;
import cz.jzitnik.ui.Stats;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.RerenderUtils;
import cz.jzitnik.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.Event;
import cz.jzitnik.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -51,17 +45,11 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
private PlayerConfig playerConfig; private PlayerConfig playerConfig;
@InjectState @InjectState
private RenderState renderState; private RenderState renderState;
@InjectConfig
private Logging logging;
@InjectState @InjectState
private PlayerMovementState playerMovementState; private PlayerMovementState playerMovementState;
@InjectDependency @InjectDependency
private Stats stats; private Stats stats;
public PlayerMoveEventHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(PlayerMoveEvent event) { public void handle(PlayerMoveEvent event) {
if (renderState.isTerminalTooSmall()) { if (renderState.isTerminalTooSmall()) {
@@ -73,13 +61,13 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
RoomCords playerCords = player.getPlayerCords(); RoomCords playerCords = player.getPlayerCords();
GameRoom currentRoom = gameState.getCurrentRoom(); GameRoom currentRoom = gameState.getCurrentRoom();
boolean isSprinting = player.getStamina() > 0 && switch (playerConfig.getSprintKey()) { boolean isSprinting = player.getStamina() > 0 && switch (playerConfig.sprintKey()) {
case CTRL -> event.getKeyStroke().isCtrlDown(); case CTRL -> event.getKeyStroke().isCtrlDown();
case SHIFT -> event.getKeyStroke().isShiftDown(); case SHIFT -> event.getKeyStroke().isShiftDown();
case ALT -> event.getKeyStroke().isAltDown(); case ALT -> event.getKeyStroke().isAltDown();
}; };
int moveStep = isSprinting ? playerConfig.getPlayerMoveDistanceSprinting() : playerConfig.getPlayerMoveDistance(); int moveStep = isSprinting ? playerConfig.playerMoveDistanceSprinting() : playerConfig.playerMoveDistance();
int originalPlayerX = playerCords.getX(); int originalPlayerX = playerCords.getX();
int originalPlayerY = playerCords.getY(); int originalPlayerY = playerCords.getY();
@@ -87,46 +75,46 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
case 'w' -> { case 'w' -> {
if (originalPlayerY <= 10) { if (originalPlayerY <= 10) {
if (originalPlayerX >= 80 && originalPlayerX <= 105) { if (originalPlayerX >= 80 && originalPlayerX <= 105) {
player.setPlayerRotation(Player.PlayerRotation.BACK); player.setPlayerRotation(PlayerRotation.BACK);
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.TOP)); eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.TOP));
} }
return; return;
} }
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() - moveStep); playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() - moveStep, player.getCollider());
player.setPlayerRotation(Player.PlayerRotation.BACK); player.setPlayerRotation(PlayerRotation.BACK);
} }
case 'a' -> { case 'a' -> {
if (originalPlayerX <= 30) { if (originalPlayerX <= 30) {
if (originalPlayerY >= 35 && originalPlayerY <= 65) { if (originalPlayerY >= 35 && originalPlayerY <= 65) {
player.setPlayerRotation(Player.PlayerRotation.LEFT); player.setPlayerRotation(PlayerRotation.LEFT);
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.LEFT)); eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.LEFT));
} }
return; return;
} }
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() - moveStep, playerCords.getY()); playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() - moveStep, playerCords.getY(), player.getCollider());
player.setPlayerRotation(Player.PlayerRotation.LEFT); player.setPlayerRotation(PlayerRotation.LEFT);
} }
case 's' -> { case 's' -> {
if (originalPlayerY >= 110) { if (originalPlayerY >= 110) {
if (originalPlayerX >= 75 && originalPlayerX <= 105) { if (originalPlayerX >= 75 && originalPlayerX <= 105) {
player.setPlayerRotation(Player.PlayerRotation.FRONT); player.setPlayerRotation(PlayerRotation.FRONT);
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.BOTTOM)); eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.BOTTOM));
} }
return; return;
} }
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() + moveStep); playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() + moveStep, player.getCollider());
player.setPlayerRotation(Player.PlayerRotation.FRONT); player.setPlayerRotation(PlayerRotation.FRONT);
} }
case 'd' -> { case 'd' -> {
if (originalPlayerX >= 155) { if (originalPlayerX >= 155) {
if (originalPlayerY >= 40 && originalPlayerY <= 60) { if (originalPlayerY >= 40 && originalPlayerY <= 60) {
player.setPlayerRotation(Player.PlayerRotation.RIGHT); player.setPlayerRotation(PlayerRotation.RIGHT);
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.RIGHT)); eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.RIGHT));
} }
return; return;
} }
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() + moveStep, playerCords.getY()); playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() + moveStep, playerCords.getY(), player.getCollider());
player.setPlayerRotation(Player.PlayerRotation.RIGHT); player.setPlayerRotation(PlayerRotation.RIGHT);
} }
} }
playerMovementState.setLastMovement(System.currentTimeMillis()); playerMovementState.setLastMovement(System.currentTimeMillis());
@@ -137,7 +125,7 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
int newPlayerX = playerCords.getX(); int newPlayerX = playerCords.getX();
int newPlayerY = playerCords.getY(); int newPlayerY = playerCords.getY();
if (logging.isShowPlayerCordsLogs()) { if (debugging.showPlayerCordsLogs()) {
log.debug("x: {}, y: {}", newPlayerX, newPlayerY); log.debug("x: {}, y: {}", newPlayerX, newPlayerY);
} }
BufferedImage playerTexture = player.getTexture(resourceManager); BufferedImage playerTexture = player.getTexture(resourceManager);
@@ -151,9 +139,10 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
int startX = start.getX(); int startX = start.getX();
int startY = start.getY(); int startY = start.getY();
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, currentRoom, room, player, playerTexture, screenBuffer, resourceManager, debugging); RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, currentRoom, room, player, screenBuffer, resourceManager, debugging, gameState.getOtherPlayers());
eventManager.emitEvent(new Event[]{ eventManager.emitEvent(new Event[]{
new SendSocketMessageEvent(new PlayerMove(playerCords, player.getPlayerRotation())),
new MouseMoveEvent(null), new MouseMoveEvent(null),
new RerenderScreen( new RerenderScreen(
new RerenderScreen.ScreenPart[]{ new RerenderScreen.ScreenPart[]{

View File

@@ -1,14 +1,13 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.events.RenderStats; import cz.jzitnik.client.events.RenderStats;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.ui.Stats; import cz.jzitnik.client.ui.Stats;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
@EventHandler(RenderStats.class) @EventHandler(RenderStats.class)
public class RenderStatsHandler extends AbstractEventHandler<RenderStats> { public class RenderStatsHandler extends AbstractEventHandler<RenderStats> {
@@ -18,10 +17,6 @@ public class RenderStatsHandler extends AbstractEventHandler<RenderStats> {
@InjectDependency @InjectDependency
private Stats stats; private Stats stats;
public RenderStatsHandler(DependencyManager dm) {
super(dm);
}
@Override @Override
public void handle(RenderStats event) { public void handle(RenderStats event) {
stats.rerender(); stats.rerender();

View File

@@ -1,32 +1,27 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalPosition;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.client.annotations.injectors.InjectConfig;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.config.Debugging; import cz.jzitnik.client.config.Debugging;
import cz.jzitnik.events.RerenderPart; import cz.jzitnik.client.events.RerenderPart;
import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.game.GameRoom; import cz.jzitnik.client.game.GameRoom;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.game.ResourceManager; import cz.jzitnik.client.game.ResourceManager;
import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.common.models.coordinates.RoomCords;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.RerenderUtils;
import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@EventHandler(RerenderPart.class) @EventHandler(RerenderPart.class)
public class RerenderPartHandler extends AbstractEventHandler<RerenderPart> { public class RerenderPartHandler extends AbstractEventHandler<RerenderPart> {
public RerenderPartHandler(DependencyManager dm) {
super(dm);
}
@InjectState @InjectState
private TerminalState terminalState; private TerminalState terminalState;
@@ -67,10 +62,10 @@ public class RerenderPartHandler extends AbstractEventHandler<RerenderPart> {
currentRoom, currentRoom,
room, room,
gameState.getPlayer(), gameState.getPlayer(),
gameState.getPlayer().getTexture(resourceManager),
screenBuffer, screenBuffer,
resourceManager, resourceManager,
debugging debugging,
gameState.getOtherPlayers()
); );
eventManager.emitEvent( eventManager.emitEvent(

View File

@@ -0,0 +1,81 @@
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);
}
}
}

View File

@@ -0,0 +1,24 @@
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);
}
}
}

View File

@@ -1,28 +1,23 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TerminalSize;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.FullRoomDraw; import cz.jzitnik.client.events.FullRoomDraw;
import cz.jzitnik.events.TerminalResizeEvent; import cz.jzitnik.client.events.TerminalResizeEvent;
import cz.jzitnik.game.GameState; import cz.jzitnik.client.game.GameState;
import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
import cz.jzitnik.ui.pixels.AlphaPixel; import cz.jzitnik.client.ui.pixels.AlphaPixel;
import cz.jzitnik.ui.pixels.Empty; import cz.jzitnik.client.ui.pixels.Empty;
import cz.jzitnik.ui.pixels.Pixel; import cz.jzitnik.client.ui.pixels.Pixel;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler; import cz.jzitnik.client.utils.events.EventManager;
import cz.jzitnik.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@EventHandler(TerminalResizeEvent.class) @EventHandler(TerminalResizeEvent.class)
public class TerminalResizeEventHandler extends AbstractEventHandler<TerminalResizeEvent> { public class TerminalResizeEventHandler extends AbstractEventHandler<TerminalResizeEvent> {
public TerminalResizeEventHandler(DependencyManager dm) {
super(dm);
}
@InjectDependency @InjectDependency
private EventManager eventManager; private EventManager eventManager;

View File

@@ -1,28 +1,21 @@
package cz.jzitnik.events.handlers; package cz.jzitnik.client.events.handlers;
import com.googlecode.lanterna.SGR; import com.googlecode.lanterna.SGR;
import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.TextCharacter;
import com.googlecode.lanterna.TextColor; import com.googlecode.lanterna.TextColor;
import com.googlecode.lanterna.screen.Screen; import com.googlecode.lanterna.screen.Screen;
import com.googlecode.lanterna.screen.TerminalScreen; import com.googlecode.lanterna.screen.TerminalScreen;
import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.events.TerminalTooSmallEvent; import cz.jzitnik.client.events.TerminalTooSmallEvent;
import cz.jzitnik.states.TerminalState; import cz.jzitnik.client.states.TerminalState;
import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.client.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.AbstractEventHandler;
import java.io.IOException; import java.io.IOException;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
@EventHandler(TerminalTooSmallEvent.class) @EventHandler(TerminalTooSmallEvent.class)
public class TerminalTooSmallEventHandler extends AbstractEventHandler<TerminalTooSmallEvent> { public class TerminalTooSmallEventHandler extends AbstractEventHandler<TerminalTooSmallEvent> {
public TerminalTooSmallEventHandler(DependencyManager dm) {
super(dm);
}
@InjectState @InjectState
private TerminalState terminalState; private TerminalState terminalState;

View File

@@ -1,4 +1,4 @@
package cz.jzitnik.game; package cz.jzitnik.client.game;
import com.googlecode.lanterna.TextColor; import com.googlecode.lanterna.TextColor;

View File

@@ -0,0 +1,10 @@
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);
}

Some files were not shown because too many files have changed in this diff Show More