Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id 'eclipse'
id 'maven-publish'
id 'idea'
id "io.freefair.lombok" version "8.10.2"
}

ext {
Expand Down Expand Up @@ -64,6 +65,8 @@ dependencies {
implementation "com.simsilica:zay-es-net:1.6.0"
implementation "com.simsilica:sio2:1.8.0"
implementation "com.simsilica:sim-ethereal:1.8.0"
implementation "com.google.guava:guava:33.4.8-jre"
implementation "org.reflections:reflections:0.10.2"
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been removing these (reflections) at work :D For security reasons. Are there any alternatives?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need scan package for classes with annotation... I don`t know any other library that can do this

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, me neither. I just designed around it at work. It is a bit of a hazard in my opinion to take this in. Is there any alternative to having to scan package classes with annotation? I know what you are trying to solve here, having to manually add the class to be de/serialized. How else we could do it better?

Copy link
Copy Markdown
Collaborator Author

@ArchDemons ArchDemons Sep 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compile-time annotation preprocessor (like lombok), but it`s rocket science for me :). I work with spring framework. Packages scan - the core of DI container and dynamic connection of the components

}

sourceSets {
Expand Down Expand Up @@ -117,7 +120,7 @@ idea {

compileJava {
// We have annotation processors in log4j, only needed for writing plugins, disable the warnings
options.compilerArgs += ["-proc:none"]
//options.compilerArgs += ["-proc:none"]
options.compilerArgs += ["-Xlint:deprecation"]
//options.compilerArgs += ["-Xlint:unchecked"]
}
Expand Down
49 changes: 49 additions & 0 deletions src/toniarts/openkeeper/common/GameEventBus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2014-2025 OpenKeeper
*
* OpenKeeper is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenKeeper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenKeeper. If not, see <http://www.gnu.org/licenses/>.
*/
package toniarts.openkeeper.common;

import com.google.common.eventbus.EventBus;

/**
*
* @author ArchDemon
*/
public class GameEventBus {

private static final GameEventBus instance = new GameEventBus();

private final EventBus eventBus = new EventBus();

public static GameEventBus getInstance() {
return instance;
}

protected GameEventBus() {
}

public void addListener(Object listener) {
eventBus.register(listener);
}

public void removeListener(Object listener) {
eventBus.unregister(listener);
}

public void publish(Object event) {
eventBus.post(event);
}
}
245 changes: 245 additions & 0 deletions src/toniarts/openkeeper/common/SelectionArea.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
package toniarts.openkeeper.common;

import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
import toniarts.openkeeper.utils.Point;
import toniarts.openkeeper.utils.WorldUtils;

/**
* @author 7willuwe : Philip Willuweit
*/
public final class SelectionArea implements Iterable<Set<Point>> {

private Vector2f start = new Vector2f();
private Vector2f end = new Vector2f();
private float scale = 1;

public SelectionArea(Vector2f start, Vector2f end) {
this.start = start;
this.end = end;
}

public SelectionArea(float appScaled) {
this.scale = appScaled;
this.start = new Vector2f(Vector2f.ZERO);
this.end = new Vector2f(Vector2f.ZERO);
}

/**
* For single square use only
*
* @param appScaled
* @param start Start position
* @param end End position
*/
public SelectionArea(float appScaled, Vector2f start, Vector2f end) {
this.start = start;
this.end = end;
this.scale = appScaled;
}

/**
* @return the start
*/
public Vector2f getStart() {
return new Vector2f(Math.min(start.x, end.x), Math.min(start.y, end.y));
}

/**
* Get the real starting coordinates, the first click
*
* @return
*/
public Vector2f getRealStart() {
return start;
}

/**
* @param position the start to set
*/
public void setStart(Vector2f position) {
start.set(position);
end.set(position);
}

/**
* @return the end
*/
public Vector2f getEnd() {
return new Vector2f(Math.max(start.x, end.x), Math.max(start.y, end.y));
}

/**
* Get the real ending coordinates, the click release
*
* @return
*/
public Vector2f getRealEnd() {
return end;
}

/**
* @param position the end to set
*/
public void setEnd(Vector2f position) {
end.set(position);
}

/**
* @return the scale
*/
public float getScale() {
return scale;
}

/**
* @param scale the scale to set
*/
public void setScale(float scale) {
this.scale = scale;
}

public Vector2f getCenter() {
return new Vector2f((end.x + start.x) / 2, (start.y + end.y) / 2);
}

/**
* @return the delta x axis
*/
public float getDeltaX() {
return (Math.abs(end.x - start.x) + 1) / scale;
}

/**
* @return the delta y axis
*/
public float getDeltaY() {
return (Math.abs(end.y - start.y) + 1) / scale;
}

@Override
public Iterator<Set<Point>> iterator() {
return new SelectionArea.AreaIterator(getRealStart(), getRealEnd());
}

public Iterator<Point> simpleIterator() {
return new SimpleIterator(getStart(), getEnd());
}

/**
* An optimized version of AbstractList.Itr
*/
public final static class AreaIterator implements Iterator<Set<Point>> {

private final Point end;
private final Point start;
private final Point realStart;
private final Point realEnd;
private final Point delta;

private Set<Point> cursor = new HashSet<>();

public AreaIterator(final Vector2f start, final Vector2f end) {
this.realStart = WorldUtils.vectorToPoint(start);
this.realEnd = WorldUtils.vectorToPoint(end);
this.end = new Point(Math.max(realStart.x, realEnd.x), Math.max(realStart.y, realEnd.y));
this.start = new Point(Math.min(realStart.x, realEnd.x), Math.min(realStart.y, realEnd.y));
this.delta = new Point(FastMath.sign(realStart.x - realEnd.x),
FastMath.sign(realStart.y - realEnd.y));
}

@Override
public boolean hasNext() {
return !(cursor.size() == 1 && cursor.contains(realStart));
}

@Override
public Set<Point> next() {
Set result = new HashSet<>();

if (cursor.isEmpty()) {
result.add(realEnd);
}

for (Point p : cursor) {
if (delta.x != 0) {
Point neighborhood = new Point(p.x + delta.x, p.y);
if (check(neighborhood)) {
result.add(neighborhood);
}
}
if (delta.y != 0) {
Point neighborhood = new Point(p.x, p.y + delta.y);
if (check(neighborhood)) {
result.add(neighborhood);
}
}
}

cursor = result;

return result;
}

private boolean check(Point p) {
return p.x <= end.x && p.x >= start.x && p.y <= end.y && p.y >= start.y;
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

@Override
public void forEachRemaining(Consumer<? super Set<Point>> consumer) {
throw new UnsupportedOperationException();
}
}

public static final class SimpleIterator implements Iterator<Point> {

private final Point start;
private final Point end;
private Point cursor;

public SimpleIterator(final Vector2f start, final Vector2f end) {
this.start = WorldUtils.vectorToPoint(start);
this.end = WorldUtils.vectorToPoint(end);
}

@Override
public boolean hasNext() {
return !end.equals(cursor);
}

@Override
public Point next() {
if (cursor == null) {
cursor = (Point) start.clone();
return cursor;
}

cursor.x++;
if (cursor.x > end.x) {
cursor.x = start.x;
cursor.y++;
}

return cursor;
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

@Override
public void forEachRemaining(Consumer<? super Point> consumer) {
throw new UnsupportedOperationException();
}
}
}
2 changes: 2 additions & 0 deletions src/toniarts/openkeeper/game/component/AttackTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

import com.simsilica.es.EntityComponent;
import com.simsilica.es.EntityId;
import toniarts.openkeeper.game.network.Transferable;

/**
* Marks that entity is attacking a target
*
* @author Toni Helenius <helenius.toni@gmail.com>
*/
@Transferable
public final class AttackTarget implements EntityComponent {

public EntityId entityId;
Expand Down
2 changes: 2 additions & 0 deletions src/toniarts/openkeeper/game/component/ChickenAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

import com.simsilica.es.EntityComponent;
import toniarts.openkeeper.game.controller.chicken.ChickenState;
import toniarts.openkeeper.game.network.Transferable;

/**
* Simple chicken AI component
*
* @author Toni Helenius <helenius.toni@gmail.com>
*/
@Transferable
public final class ChickenAi implements EntityComponent {

public double stateStartTime;
Expand Down
2 changes: 2 additions & 0 deletions src/toniarts/openkeeper/game/component/ChickenGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
package toniarts.openkeeper.game.component;

import com.simsilica.es.EntityComponent;
import toniarts.openkeeper.game.network.Transferable;

/**
* Just a tagging component for chicken generators
*
* @author Toni Helenius <helenius.toni@gmail.com>
*/
@Transferable
public final class ChickenGenerator implements EntityComponent {

/**
Expand Down
2 changes: 2 additions & 0 deletions src/toniarts/openkeeper/game/component/CreatureAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

import com.simsilica.es.EntityComponent;
import toniarts.openkeeper.game.controller.creature.CreatureState;
import toniarts.openkeeper.game.network.Transferable;

/**
* Simple creature AI component
*
* @author Toni Helenius <helenius.toni@gmail.com>
*/
@Transferable
public final class CreatureAi implements EntityComponent {

public double stateStartTime;
Expand Down
2 changes: 2 additions & 0 deletions src/toniarts/openkeeper/game/component/CreatureComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
package toniarts.openkeeper.game.component;

import com.simsilica.es.EntityComponent;
import toniarts.openkeeper.game.network.Transferable;

/**
* Simple creature component
*
* @author Toni Helenius <helenius.toni@gmail.com>
*/
@Transferable
public final class CreatureComponent implements EntityComponent {

public String name;
Expand Down
Loading
Loading