package org.multiverseking.field.battle; import com.jme3.app.Application; import com.jme3.app.SimpleApplication; import com.jme3.app.state.AbstractAppState; import com.jme3.app.state.AppStateManager; import com.jme3.collision.CollisionResult; import com.jme3.collision.CollisionResults; import com.jme3.input.controls.ActionListener; import com.jme3.math.FastMath; import com.jme3.math.Ray; import com.jme3.scene.Spatial; import com.simsilica.es.Entity; import com.simsilica.es.EntityComponent; import com.simsilica.es.EntityData; 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.mousepicking.GridMouseControlAppState; import org.hexgridapi.events.MouseInputEvent; import org.hexgridapi.events.MouseInputEvent.MouseInputEventType; import org.hexgridapi.events.MouseRayListener; import org.hexgridapi.utility.Rotation; import org.multiverseking.card.CardRenderComponent; import org.multiverseking.card.attribut.CardRenderPosition; import org.multiverseking.core.EntityDataAppState; import org.multiverseking.core.utility.SubSystem; import org.multiverseking.field.collision.CollisionSystem; import org.multiverseking.utility.component.HealthComponent; import org.multiverseking.utility.component.InfluenceComponent; import org.multiverseking.field.position.HexMovementSystem; import org.multiverseking.field.position.component.HexPositionComponent; import org.multiverseking.field.position.component.MoveToComponent; import org.multiverseking.loader.EntityLoader; import org.multiverseking.loader.PlayerLoader; import org.multiverseking.loader.TitanLoader; import org.multiverseking.render.AbstractRender.RenderType; import org.multiverseking.render.RenderComponent; import org.multiverseking.render.RenderSystem; import org.multiverseking.render.animation.Animation; import org.multiverseking.render.animation.AnimationComponent; import org.multiverseking.render.animation.AnimationSystem; /** * TODO: This do too much work should be split on multiple part as : * Battle Unit Control System / Battle Initialisation * * @author roah * @deprecated need to be rework */ public class BattleSystem extends AbstractAppState implements MouseRayListener, SubSystem { private final HexCoordinate startPosition; private SimpleApplication app; private EntityData entityData; private MapData mapData; private RenderSystem renderSystem; private GridMouseControlAppState mouseSystem; private Action currentAction = null; private EntityId inspectedId = null; private EntityId playerCore; public BattleSystem(HexCoordinate startPosition) { this.startPosition = startPosition; } @Override public void initialize(AppStateManager stateManager, Application app) { this.app = (SimpleApplication) app; entityData = app.getStateManager().getState(EntityDataAppState.class).getEntityData(); mapData = app.getStateManager().getState(AbstractHexGridAppState.class).getMapData(); // debugSystem = app.getStateManager().getState(AreaEventRenderDebugSystem.class); // if (mapData.getAllChunkPos().isEmpty()) { // mapData.addChunk(new Vector2Int(), null); // } if(app.getStateManager().getState(CollisionSystem.class) == null){ app.getStateManager().attach(new CollisionSystem()); } if(app.getStateManager().getState(AnimationSystem.class) == null){ app.getStateManager().attach(new AnimationSystem()); } if(app.getStateManager().getState(HexMovementSystem.class) == null){ app.getStateManager().attach(new HexMovementSystem()); } // if (app.getStateManager().getState(RenderSystem.class) == null) { // app.getStateManager().attach(new RenderSystem()); //// throw new UnsatisfiedLinkError("This System need RenderSystem and AreaMouseInputSystem to work."); // } // battleGUI = new BattleGUI(((MultiverseMain) app).getScreen(), app.getCamera(), this); renderSystem = app.getStateManager().getState(RenderSystem.class); // iNode = renderSystem.addSubSystemNode("InteractiveNode"); renderSystem.registerSubSystem(this, true); mouseSystem = app.getStateManager().getState(GridMouseControlAppState.class); mouseSystem.register(this); initialisePlayerCore(); /** * Init the testingUnit. */ // addEntityTitan("TuxDoll"); // addEntityTitan("Gilga"); // camToStartPosition(); super.initialized = true; } private void initialisePlayerCore() { // HexCoordinate startPosition = app.getStateManager().getState(AreaEventSystem.class).getStartPosition(); // if (debugSystem != null) { // debugSystem.showDebug(false, startPosition, this); // } PlayerLoader properties = PlayerLoader.getInstance(app.getAssetManager()); playerCore = entityData.createEntity(); entityData.setComponents(playerCore, new RenderComponent("Well", RenderType.Core), new HexPositionComponent(startPosition, Rotation.A, this), new AnimationComponent(Animation.SUMMON), new HealthComponent(properties.getLevel() * 10), new InfluenceComponent((byte) (1 + FastMath.floor((float) properties.getLevel() / 25f)))); } private void removePlayerCore() { // HexCoordinate startPosition = app.getStateManager().getState(AreaEventSystem.class).getStartPosition(); // if (debugSystem != null) { // debugSystem.showDebug(true, startPosition, this); // } entityData.removeEntity(playerCore); } /** * Move the camera to the center of the map. */ // private void camToStartPosition() { // HexCoordinate startPosition = app.getStateManager().getState(AreaEventSystem.class).getStartPosition(); // Vector3f center = startPosition.toWorldPosition(); //// Vector3f center = new HexCoordinate(HexCoordinate.OFFSET, //// new Vector2Int(HexSetting.CHUNK_SIZE / 2, HexSetting.CHUNK_SIZE / 2)).toWorldPosition(); // ((HexGridEditorMain) app).getRtsCam().setCenter(new Vector3f(center.x + 3, 15, center.z + 3)); // } public void addEntityTitan(String name, HexCoordinate position) { EntityLoader loader = new EntityLoader(app); TitanLoader load = loader.loadTitanStats(name); // HexCoordinate position = new HexCoordinate(HexCoordinate.OFFSET,HexSetting.CHUNK_SIZE / 2, HexSetting.CHUNK_SIZE / 2); entityData.setComponents(entityData.createEntity(), new CardRenderComponent(name, CardRenderPosition.FIELD, RenderType.Titan), new RenderComponent(name, RenderType.Titan), new HexPositionComponent(position, Rotation.C), new AnimationComponent(Animation.SUMMON), load.getInitialStatsComponent(), load.getInitialStatsComponent().getMovementComponent()); } @Override public MouseInputEvent MouseRayInputAction(MouseInputEventType mouseInputType, Ray ray) { EntitySet entities = entityData.getEntities(RenderComponent.class, HexPositionComponent.class); if (entities.isEmpty()) { return null; } if (mouseInputType.equals(MouseInputEventType.RMB)) { CollisionResults results = renderSystem.subSystemCollideWith(this, ray); if (results.size() > 0) { CollisionResult closest = results.getClosestCollision(); for (Entity e : entities) { Spatial s = closest.getGeometry().getParent(); do { if (s != null && s.getName().equals(renderSystem.getSpatialName(e.getId()))) { // mouseSystem.setDebugPosition(closest.getContactPoint()); HexCoordinate pos = entityData.getComponent(e.getId(), HexPositionComponent.class).getPosition(); return new MouseInputEvent(MouseInputEventType.RMB, pos, mapData.getTile(pos).getHeight(), ray, closest); } s = s.getParent(); } while (s != null && !s.getParent().getName().equals(renderSystem.getRenderNodeName())); } } } return null; } @Override public void onMouseAction(MouseInputEvent event) { if (event.getType().equals(MouseInputEventType.LMB)) { if (currentAction != null) { confirmAction(event.getPosition()); } else { Entity e = checkEntities(event.getPosition()); if (e != null) { openEntityPropertiesMenu(e); } } } else if (event.getType().equals(MouseInputEventType.RMB)) { // Used when the spatial is not selected directly. if (currentAction == null) { Entity e = checkEntities(event.getPosition()); if (e != null && entityData.getComponent(e.getId(), MoveToComponent.class) == null) { openEntityActionMenu(e, event.getPosition()); } } } } private Entity checkEntities(HexCoordinate coord) { EntitySet entities = entityData.getEntities(RenderComponent.class, HexPositionComponent.class); for (Entity e : entities) { if (!e.get(RenderComponent.class).getRenderType().equals(RenderType.Debug)) { HexPositionComponent posComp = entityData.getComponent(e.getId(), HexPositionComponent.class); if (posComp != null && posComp.getPosition().equals(coord)) { return e; } } } return null; } private void openEntityActionMenu(Entity e, HexCoordinate pos) { // MapData mapData = app.getStateManager().getState(HexSystemAppState.class).getMapData(); // battleGUI.showActionMenu(pos, e.getId(), e.get(RenderComponent.class).getRenderType()); } private void openEntityPropertiesMenu(Entity e) { if (inspectedId == null || !inspectedId.equals(e.getId())) { ArrayList<EntityComponent> comps = new ArrayList<>(); RenderType renderType = e.get(RenderComponent.class).getRenderType(); switch (renderType) { case Core: comps.add(entityData.getComponent(e.getId(), HealthComponent.class)); comps.add(entityData.getComponent(e.getId(), InfluenceComponent.class)); // app.getStateManager().getState(AbstractHexGridAppState.class).showAreaRange( // e.get(HexPositionComponent.class).getPosition(), ((InfluenceComponent) comps.get(1)).getRange(), ColorRGBA.Red); break; case Debug: break; case Environment: break; case Titan: break; case Unit: break; default: throw new UnsupportedOperationException(e.get(RenderComponent.class).getRenderType() + " is not currently supported."); } // battleGUI.statsWindow(e.getId(), renderType, comps); inspectedId = e.getId(); } } void setAction(EntityId id, Action action) { switch (action) { case MOVE: if (!mouseSystem.setCursorPulseMode(this)) { return; } inspectedId = id; currentAction = action; //Register the input for this system app.getInputManager().addListener(fieldInputListener, MouseInputEventType.RMB.toString()); break; case ABILITY: break; case CUSTOM: /** * TODO : For action made by external user, Data have to be * loaded from files. */ break; default: throw new UnsupportedOperationException("Action type not implemented."); } } private void confirmAction(HexCoordinate eventPosition) { if (currentAction.equals(Action.MOVE)) { //movement action entityData.setComponent(inspectedId, new MoveToComponent(eventPosition)); } unregisterInput(); } private void actionCancel() { // mouseSystem.setCursor(entityData.getComponent(inspectedId, HexPositionComponent.class).getPosition()); currentAction = null; unregisterInput(); } private void unregisterInput() { inspectedId = null; currentAction = null; mouseSystem.setCursorPulseMode(this); //Unregister the input for this system app.getInputManager().removeListener(fieldInputListener); } private ActionListener fieldInputListener = new ActionListener() { @Override public void onAction(String name, boolean keyPressed, float tpf) { if (name.equals(MouseInputEventType.RMB.toString()) && !keyPressed) { actionCancel(); } } }; public void reloadSystem() { // mapData.Cleanup(); // mapData.addChunk(new Vector2Int(), null); // camToStartPosition(); } @Override public void cleanup() { // battleGUI.removeFromScreen(); removePlayerCore(); mapData.Cleanup(); renderSystem.removeSubSystem(this, false); app.getStateManager().detach(app.getStateManager().getState(CollisionSystem.class)); app.getStateManager().detach(app.getStateManager().getState(AnimationSystem.class)); app.getStateManager().detach(app.getStateManager().getState(HexMovementSystem.class)); } @Override public void rootSystemIsRemoved() { app.getStateManager().detach(this); } public enum Action { MOVE, ABILITY, CUSTOM; } }