Skip to content

Commit

Permalink
feat: working navtower rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
vinceh121 committed May 28, 2024
1 parent 4ac5001 commit 94e0240
Show file tree
Hide file tree
Showing 13 changed files with 374 additions and 8 deletions.
53 changes: 53 additions & 0 deletions android/assets/prototypes/navtowers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"j_navtower01": {
"artifactModel": "orig/j_navigationtower01.n/j_navigationtower01.obj",
"artifactTexture": "orig/j_navigationtower01.n/texturealpha.ktx",
"artifactColor": {
"r": 1.0,
"g": 0.1,
"b": 0.0,
"a": 0.0
},
"rotate": true,
"pickupZoneRadius": 2.0,
"displayModels": [
{
"relativeTransform": {
"translation": [
0.0,
0.0,
0.0
],
"rotation": [
0.0,
0.0,
0.0,
1.0
],
"scale": [
1.0,
1.0,
1.0
]
},
"textureAttributes": [
],
"displayModel": "orig/j_navigationtower01.n/machine.obj",
"displayTexture": "orig/j_navigationtower01.n/texturealpha.ktx"
}
],
"collisionModel": "orig/j_navigationtower01.n/collide.obj",
"buildTime": 10,
"red": false,
"artefactScale": 0.05,
"interactZoneRadius": 11.0,
"interactZoneHeight": 20.0,
"energyRequired": 25,
"slotType": "NAVTOWER",
"cameraOffset": [
0,
16,
-6.5
]
}
}
2 changes: 2 additions & 0 deletions core/src/me/vinceh121/wanderer/PrototypeRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import me.vinceh121.wanderer.building.IslandPrototype;
import me.vinceh121.wanderer.building.LighthousePrototype;
import me.vinceh121.wanderer.building.NavigationTowerPrototype;
import me.vinceh121.wanderer.character.CharacterPrototype;
import me.vinceh121.wanderer.entity.PropPrototype;
import me.vinceh121.wanderer.entity.guntower.MachineGunGuntowerPrototype;
Expand Down Expand Up @@ -53,6 +54,7 @@ public void loadDefaults() throws StreamReadException, DatabindException, IOExce
this.readPrototypes(Gdx.files.internal("prototypes/machinegunGuntowers.json"),
MachineGunGuntowerPrototype.class);
this.readPrototypes(Gdx.files.internal("prototypes/machinegunPlanes.json"), MachineGunPlanePrototype.class);
this.readPrototypes(Gdx.files.internal("prototypes/navtowers.json"), NavigationTowerPrototype.class);
}

public void clear() {
Expand Down
7 changes: 7 additions & 0 deletions core/src/me/vinceh121/wanderer/Wanderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import me.vinceh121.wanderer.entity.AbstractEntity;
import me.vinceh121.wanderer.entity.IControllableEntity;
import me.vinceh121.wanderer.entity.ILivingEntity;
import me.vinceh121.wanderer.entity.NavigationWaypoint;
import me.vinceh121.wanderer.entity.Prop;
import me.vinceh121.wanderer.i18n.I18N;
import me.vinceh121.wanderer.input.Input;
Expand Down Expand Up @@ -295,6 +296,12 @@ public boolean inputDown(final Input in) {
this.setPlayerClan(this.playerClan);

this.controlEntity(john);

final NavigationWaypoint way = new NavigationWaypoint(this);
way.setTranslation(island.getTranslation().cpy().add(50, 0, 50));
way.setEnabled(true);
way.setLabel("1");
this.addEntity(way);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions core/src/me/vinceh121/wanderer/ai/AIController.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package me.vinceh121.wanderer.ai;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.IControllableEntity;
import me.vinceh121.wanderer.entity.AbstractEntity;

public abstract class AIController<T extends IControllableEntity> {
public abstract class AIController<T extends AbstractEntity> {
protected final Wanderer game;
protected final T target;

Expand Down
4 changes: 2 additions & 2 deletions core/src/me/vinceh121/wanderer/ai/Task.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package me.vinceh121.wanderer.ai;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.IControllableEntity;
import me.vinceh121.wanderer.entity.AbstractEntity;

public abstract class Task<T extends IControllableEntity> {
public abstract class Task<T extends AbstractEntity> {
/**
* @param delta Delta time in seconds
* @param game TODO
Expand Down
4 changes: 2 additions & 2 deletions core/src/me/vinceh121/wanderer/ai/TaskAIController.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package me.vinceh121.wanderer.ai;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.IControllableEntity;
import me.vinceh121.wanderer.entity.AbstractEntity;

public class TaskAIController<T extends IControllableEntity> extends AIController<T> {
public class TaskAIController<T extends AbstractEntity> extends AIController<T> {
private Task<T> currentTask;

public TaskAIController(Wanderer game, T target) {
Expand Down
52 changes: 52 additions & 0 deletions core/src/me/vinceh121/wanderer/building/Island.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package me.vinceh121.wanderer.building;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject.CollisionFlags;
Expand All @@ -13,10 +16,13 @@

import me.vinceh121.wanderer.PrototypeRegistry;
import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.ai.Task;
import me.vinceh121.wanderer.ai.TaskAIController;
import me.vinceh121.wanderer.character.CharacterW;
import me.vinceh121.wanderer.entity.AbstractClanLivingEntity;
import me.vinceh121.wanderer.entity.AbstractEntity;
import me.vinceh121.wanderer.entity.DisplayModel;
import me.vinceh121.wanderer.entity.NavigationWaypoint;
import me.vinceh121.wanderer.phys.ContactListenerAdapter;
import me.vinceh121.wanderer.phys.IContactListener;

Expand All @@ -28,6 +34,7 @@ public class Island extends AbstractClanLivingEntity {
private final Vector3 velocity = new Vector3(), placeCameraPosition = new Vector3(),
placeCameraDirection = new Vector3();
private final IContactListener characterContactListener;
private TaskAIController<Island> aiController;

public Island(final Wanderer game, final IslandPrototype prototype) {
super(game);
Expand Down Expand Up @@ -85,13 +92,24 @@ public void onContactEnded(final btCollisionObject colObj0, final btCollisionObj
}
};
game.getPhysicsManager().addContactListener(this.characterContactListener);

this.aiController = new TaskAIController<Island>(game, this);
}

@Override
public void onDeath() {
// TODO
}

@Override
public void tick(float delta) {
super.tick(delta);

if (this.aiController != null) {
this.aiController.tick(delta);
}
}

/**
* @param value
* @see com.badlogic.gdx.utils.Array#add(java.lang.Object)
Expand Down Expand Up @@ -256,4 +274,38 @@ public void dispose() {
this.game.getPhysicsManager().removeContactListener(this.characterContactListener);
super.dispose();
}

public TaskAIController<Island> getAiController() {
return this.aiController;
}

public static class NavigationGoto extends Task<Island> {
private final NavigationWaypoint waypoint;
private float angleProgress, targetAngle = Float.NaN, initialAngle = Float.NaN;

public NavigationGoto(NavigationWaypoint waypoint) {
this.waypoint = waypoint;
}

@Override
public Task<Island> process(float delta, Wanderer game, Island controlled) {
final Quaternion dirDiff = new Quaternion()
.setFromCross(waypoint.getTranslation().sub(controlled.getTranslation()), new Vector3(0, 1, 0));

if (Float.isNaN(this.targetAngle)) {
this.targetAngle = dirDiff.getYawRad();
}
if (Float.isNaN(this.initialAngle)) {
this.initialAngle = (controlled.getRotation().getYawRad() - MathUtils.PI * 1.5f) % MathUtils.PI2;
}

this.angleProgress += MathUtils.PI / 8 * delta;
this.angleProgress = Math.min(this.angleProgress, 1);
controlled.setYaw(Interpolation.smooth.apply(this.initialAngle, this.targetAngle, this.angleProgress) - MathUtils.HALF_PI);

controlled.updateBuildings();

return null;
}
}
}
120 changes: 120 additions & 0 deletions core/src/me/vinceh121/wanderer/building/NavigationTower.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package me.vinceh121.wanderer.building;

import java.util.List;
import java.util.stream.Collectors;

import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.math.Vector3;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.NavigationWaypoint;
import me.vinceh121.wanderer.i18n.I18N;
import me.vinceh121.wanderer.input.Input;
import me.vinceh121.wanderer.input.InputListener;
import me.vinceh121.wanderer.input.InputListenerAdapter;

public class NavigationTower extends AbstractControllableBuilding {
private final NavigationTowerPrototype prototype;
private NavigationWaypoint currentWaypoint;

public NavigationTower(final Wanderer game, final NavigationTowerPrototype prototype) {
super(game, prototype);
this.prototype = prototype;

this.setControlMessage(/* Popup when getting close to navtower */ I18N.gettext("Navigation Tower"));
}

public List<NavigationWaypoint> getAvailableWaypoints() {
final Vector3 islandTrans = this.getIsland().getTranslation();

return this.game.findEntitiesByClass(NavigationWaypoint.class)
.filter(w -> w.isEnabled() && w.getTranslation().dst(islandTrans) > 2)
.sorted((w1, w2) -> Double.compare(w1.getTranslation().dst(islandTrans),
w2.getTranslation().dst(islandTrans)))
.collect(Collectors.toUnmodifiableList());
}

private void nextWaypoint(int offset) {
final List<NavigationWaypoint> waypoints = this.getAvailableWaypoints();

if (waypoints.isEmpty()) {
return;
}

int next = this.currentWaypoint == null ? 0 : (waypoints.indexOf(this.currentWaypoint) + offset) % waypoints.size();

if (next < 0) {
next = waypoints.size() - next;
}

this.currentWaypoint = waypoints.get(next);
}

private void start() {
if (this.currentWaypoint != null) {
this.getIsland().getAiController().setCurrentTask(new Island.NavigationGoto(currentWaypoint));
} else {
this.game.showMessage(I18N.gettext("No waypoint available"));
}
}

@Override
public void tick(float delta) {
super.tick(delta);

if (this.isControlled()) {
this.moveCamera();
}
}

private void moveCamera() {
final PerspectiveCamera cam = this.game.getCamera();
final float offY = this.prototype.getCameraOffset().y;
final float offZ = this.prototype.getCameraOffset().z;

final Vector3 direction;

if (this.currentWaypoint == null) {
direction = new Vector3(1, 0, 0);
} else {
direction = this.currentWaypoint.getTranslation().sub(this.getTranslation());
}

final Vector3 position = cam.position;
position.set(direction);
position.scl(offZ);
position.add(0, offY, 0);
position.add(this.getTranslation());

cam.direction.set(direction);

cam.update();
}

@Override
public void onTakeControl() {
super.onTakeControl();

if (this.currentWaypoint != null) {
this.nextWaypoint(1);
}
}

@Override
public InputListener createInputProcessor() {
return new InputListenerAdapter(0) {
@Override
public boolean inputDown(Input in) {
if (in == Input.SCROLL_BELT_RIGHT) {
nextWaypoint(1);
} else if (in == Input.SCROLL_BELT_LEFT) {
nextWaypoint(-1);
} else if (in == Input.FIRE) {
start();
}

return false;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.vinceh121.wanderer.building;

import com.badlogic.gdx.math.Vector3;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.AbstractEntity;

public class NavigationTowerPrototype extends AbstractBuildingPrototype {
private Vector3 cameraOffset = new Vector3();

public Vector3 getCameraOffset() {
return cameraOffset;
}

public void setCameraOffset(Vector3 cameraOffset) {
this.cameraOffset = cameraOffset;
}

@Override
public AbstractEntity create(final Wanderer game) {
return new NavigationTower(game, this);
}
}
4 changes: 3 additions & 1 deletion core/src/me/vinceh121/wanderer/building/PreviewBuilding.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.badlogic.gdx.physics.bullet.dynamics.btDiscreteDynamicsWorld;

import me.vinceh121.wanderer.Wanderer;
import me.vinceh121.wanderer.entity.AbstractEntity;
import me.vinceh121.wanderer.entity.DisplayModel;
import me.vinceh121.wanderer.entity.IControllableEntity;

Expand Down Expand Up @@ -39,7 +40,8 @@ public float addSingleResult(final btManifoldPoint cp, final btCollisionObjectWr
final int partId0, final int index0, final btCollisionObjectWrapper colObj1Wrap, final int partId1,
final int index1) {
final int idx = colObj1Wrap.getCollisionObject().getUserIndex();
if (PreviewBuilding.this.game.getEntity(idx) instanceof IControllableEntity) {
final AbstractEntity entity = PreviewBuilding.this.game.getEntity(idx);
if (entity instanceof IControllableEntity && !(entity instanceof Island)) {
PreviewBuilding.this.setBlocked(true);
}
return 0;
Expand Down
1 change: 0 additions & 1 deletion core/src/me/vinceh121/wanderer/character/CharacterW.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ private void moveCamera() {
@Override
public void onDeath() {
// TODO
CharacterW.LOG.debug("Dead!");
}

public void processInput() {
Expand Down
Loading

0 comments on commit 94e0240

Please sign in to comment.