package org.multiverseking.field.position; import org.multiverseking.field.position.component.HexPositionComponent; 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 java.util.ArrayList; import org.hexgridapi.core.AbstractHexGridAppState; import org.hexgridapi.core.coordinate.HexCoordinate; import org.hexgridapi.core.data.MapData; import org.hexgridapi.core.geometry.HexSetting; import org.hexgridapi.events.MapDataListener; import org.hexgridapi.events.TileChangeEvent; import org.multiverseking.core.utility.EntitySystemAppState; import org.multiverseking.core.utility.SubSystem; import org.multiverseking.render.RenderComponent; import org.multiverseking.render.RenderSystem; /** * Handle the HEX position rendering of all entity. * @TODO Spatial parenting may cause issue with positionning * @author roah */ public class HexPositionSystem extends EntitySystemAppState implements SubSystem { private MapData mapData; private RenderSystem renderSystem; private ArrayList<EntityId> positionCulling = new ArrayList<>(); // Used for spatials position handled by subsustem (aka position culling?) private MapDataListener tileChangeListener = new MapDataListener() { @Override public void onTileChange(TileChangeEvent[] events) { for (Entity e : entities) { HexCoordinate entityPos = e.get(HexPositionComponent.class).getPosition(); for (int i = 0; i < events.length; i++) { if (entityPos.equals(events[i].getTilePos())) { Spatial s = renderSystem.getSpatial(e.getId()); float posY = events[i].getNewTile().getHeight() * HexSetting.FLOOR_OFFSET + 0.1f; s.setLocalTranslation(s.getLocalTranslation().x, posY, s.getLocalTranslation().z); break; } } } } }; @Override protected EntitySet initialiseSystem() { renderSystem = app.getStateManager().getState(RenderSystem.class); renderSystem.registerSubSystem(this); mapData = app.getStateManager().getState(AbstractHexGridAppState.class).getMapData(); mapData.register(tileChangeListener); app.getStateManager().getState(RenderSystem.class).registerSubSystem(this); return entityData.getEntities(RenderComponent.class, HexPositionComponent.class); } @Override protected void updateSystem(float tpf) { } @Override protected void addEntity(Entity e) { RenderComponent render = entityData.getComponent(e.getId(), RenderComponent.class); if (render != null && render.getParent() != null) { entityData.removeComponent(e.getId(), HexPositionComponent.class); // updateSpatialTransform(e); // todo update the position to the parent } else { updateSpatialTransform(e); } } @Override protected void updateEntity(Entity e) { RenderComponent render = entityData.getComponent(e.getId(), RenderComponent.class); if (render != null && render.getParent() != null) { entityData.removeComponent(e.getId(), HexPositionComponent.class); // updateSpatialTransform(e); // todo update the position to the parent } else { updateSpatialTransform(e); } updateSpatialTransform(e); // todo parenting handling } @Override protected void removeEntity(Entity e) { if(e.get(HexPositionComponent.class) != null){ entityData.removeComponent(e.getId(), HexPositionComponent.class); } positionCulling.remove(e.getId()); } @Override protected void cleanupSystem() { if(renderSystem != null) { renderSystem.removeSubSystem(this, false); } mapData.unregister(tileChangeListener); } /** * @todo better implementation in case of multiple system wanting * to get the control of the position of an entity at the same moment. */ public void registerEntityForCulling(EntityId id) { positionCulling.add(id); } /** * @todo better implementation in case of multiple system wanting * to get the control of the position of an entity at the same moment. */ public void removeEntityFromCulling(EntityId id) { positionCulling.remove(id); Entity e = entities.getEntity(id); if(e != null){ updateSpatialTransform(e); } } @Override public void rootSystemIsRemoved() { app.getStateManager().detach(this); } private void updateSpatialTransform(Entity e) { if(positionCulling.contains(e.getId())){ return; } Spatial s = renderSystem.getSpatial(e.getId()); if(s != null){ Vector3f pos; if (mapData.getTile(e.get(HexPositionComponent.class).getPosition()) == null) { pos = e.get(HexPositionComponent.class).getPosition().toWorldPosition(); } else { pos = e.get(HexPositionComponent.class).getPosition() .toWorldPosition(mapData.getTile( e.get(HexPositionComponent.class).getPosition()).getHeight()); } pos.y += 0.01f; s.setLocalTranslation(pos); s.setLocalRotation(e.get(HexPositionComponent.class).getRotation().toQuaternion()); } } }