package org.multiverseking.render.camera; import com.jme3.math.Vector3f; import com.jme3.scene.Spatial; import com.simsilica.es.Entity; import com.simsilica.es.EntityId; import com.simsilica.es.EntitySet; import org.hexgridapi.core.AbstractHexGridAppState; import org.hexgridapi.core.camera.RTSCamera; import org.hexgridapi.core.geometry.buffer.BufferPositionProvider; import org.hexgridapi.core.geometry.buffer.HexGridBuffer; import org.multiverseking.core.utility.EntitySystemAppState; import org.multiverseking.core.utility.SubSystem; import org.multiverseking.render.RenderSystem; /** * Used to bound the camera, or {@link HexGridBuffer} to the player position. * Make the grid being generated around the tracked character. * Make the camera being lock to the tracked character. * * @author roah */ public class CameraControlSystem extends EntitySystemAppState implements SubSystem, BufferPositionProvider { private RTSCamera camera; private EntityId trackedEntity; private Spatial trackedSpatial; private RenderSystem renderSystem; // Set this to false to free the camera from the tracked character private boolean lockCamera = true; @Override protected EntitySet initialiseSystem() { renderSystem = app.getStateManager().getState(RenderSystem.class); renderSystem.registerSubSystem(this); camera = app.getStateManager().getState(RTSCamera.class); updateProvider(true); return entityData.getEntities(CameraTrackComponent.class); } @Override protected void updateSystem(float tpf) { if (trackedSpatial == null && !entities.isEmpty()) { trackedSpatial = renderSystem.getSpatial(trackedEntity); } // this part bound the camera position to the character position if (lockCamera && trackedSpatial != null) { camera.setCenter(trackedSpatial.getLocalTranslation()); } } @Override protected void addEntity(Entity e) { setTrackingTo(e.getId()); } @Override protected void updateEntity(Entity e) { setTrackingTo(e.getId()); } @Override protected void removeEntity(Entity e) { setTrackingTo(null); } private void setTrackingTo(EntityId id) { if (id != null) { if (trackedEntity != null && !trackedEntity.equals(id)) { entityData.removeComponent(trackedEntity, CameraTrackComponent.class); } else if (trackedEntity != null) { return; } trackedEntity = id; trackedSpatial = renderSystem.getSpatial(id); } else { trackedEntity = null; trackedSpatial = null; } } @Override protected void cleanupSystem() { renderSystem.removeSubSystem(this, true); } @Override public void rootSystemIsRemoved() { app.getStateManager().detach(this); } @Override public Vector3f getBufferPosition() { return trackedSpatial.getLocalTranslation(); } @Override public void resetToOriginPosition(Vector3f pos) { } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); updateProvider(enabled); } private void updateProvider(boolean enable) { if(!enable) { app.getStateManager().getState(AbstractHexGridAppState.class) .setBufferPositionProvider(app.getStateManager().getState(RTSCamera.class)); } else { app.getStateManager().getState(AbstractHexGridAppState.class) .setBufferPositionProvider(this); } } }