package net.mostlyoriginal.game.system.ship;
import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Wire;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.utils.EntityBuilder;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.math.MathUtils;
import net.mostlyoriginal.api.component.basic.Bounds;
import net.mostlyoriginal.api.component.basic.Pos;
import net.mostlyoriginal.api.component.graphics.Anim;
import net.mostlyoriginal.api.component.graphics.Renderable;
import net.mostlyoriginal.game.component.ship.ShipComponent;
import net.mostlyoriginal.game.component.ui.Clickable;
import net.mostlyoriginal.game.system.ui.ConstructionSystem;
/**
* Holds a spatial map of the ship.
*
* @author Daan van Yperen
*/
@Wire
public class ShipComponentSystem extends EntityProcessingSystem {
public static final int MARGIN_TOP = 32;
public static final int MARGIN_LEFT = 16;
protected ComponentMapper<Pos> mPos;
protected ComponentMapper<Anim> mAnim;
protected ComponentMapper<ShipComponent> mShipComponent;
protected ComponentMapper<Renderable> mRenderable;
private HullSystem hullSystem;
private AccelerationEffectSystem accelerationEffectSystem;
private InventorySystem inventorySystem;
private ConstructionSystem constructionSystem;
public ShipComponentSystem() {
super(Aspect.getAspectForAll(ShipComponent.class, Pos.class, Anim.class));
}
protected ComponentMapper<ShipComponent> mc;
public static final int MAX_X = 32;
public static final int MAX_Y = 16;
Entity emap[][] = new Entity[MAX_Y][MAX_X];
@Override
protected void initialize() {
super.initialize();
int shipCenterX = 8;
int shipCenterY = 8;
// initialize basic ship.
// create test expansion slot.
final ShipComponent.State constructed = ShipComponent.State.UNDER_CONSTRUCTION;
//createComponent(shipCenterX -1, shipCenterY+1, ShipComponent.Type.ENGINE, constructed);
for (int x = -1; x <= 1; x++) {
for (int y = -2; y <= 2; y++) {
createComponent(shipCenterX+x, shipCenterY+y, ShipComponent.Type.HULL, constructed);
}
}
createComponent(shipCenterX - 2, shipCenterY, ShipComponent.Type.CHAIN, constructed);
createComponent(shipCenterX - 3, shipCenterY, ShipComponent.Type.CHAIN, constructed);
createComponent(shipCenterX - 4, shipCenterY, ShipComponent.Type.CHAIN, constructed);
hullSystem.dirty();
}
/**
* attempts to create a component at coordinates. will fail if out of bounds or already one there.
*/
public Entity createComponent(int gridX, int gridY, ShipComponent.Type type, ShipComponent.State state) {
if (gridY < 0 || gridX < 0 || gridX >= MAX_X || gridY >= MAX_Y) return null;
if (get(gridX, gridY) == null) {
Entity entity = new EntityBuilder(world).with(
new Pos(),
new Anim(),
new Renderable(),
new ShipComponent(type, gridX, gridY, ShipComponent.State.UNDER_CONSTRUCTION),
new Bounds(0, 0, 8, 8),
new Clickable()).build();
set(gridX, gridY, entity);
if (state == ShipComponent.State.CONSTRUCTED) {
constructionSystem.complete(entity);
}
return entity;
}
return null;
}
@Override
protected void inserted(Entity e) {
if (mc.has(e)) {
ShipComponent shipComponent = mc.get(e);
if (get(shipComponent.gridX, shipComponent.gridY) == null) {
set(shipComponent.gridX, shipComponent.gridY, e);
}
}
super.inserted(e);
}
public Entity get(int x, int y) {
if (x < 0 || y < 0 || x >= MAX_X || y >= MAX_Y) return null;
return emap[y][x];
}
public void set(int x, int y, Entity e) {
if (x < 0 || y < 0 || x >= MAX_X || y >= MAX_Y) return;
emap[y][x] = e;
}
@Override
protected void removed(Entity e) {
if (mc.has(e)) {
ShipComponent shipComponent = mc.get(e);
if (get(shipComponent.gridX, shipComponent.gridY) == e) {
set(shipComponent.gridX, shipComponent.gridY, null);
}
}
super.removed(e);
}
@Override
protected void begin() {
super.begin();
}
@Override
protected void process(Entity e) {
Pos pos = mPos.get(e);
ShipComponent shipComponent = mc.get(e);
pos.x = shipComponent.gridX * 8 + MARGIN_LEFT + shipComponent.type.xOffset + 10f * accelerationEffectSystem.speedFactor;
pos.y = shipComponent.gridY * 8 + MARGIN_TOP;
final Renderable renderable = mRenderable.get(e);
renderable.layer = shipComponent.type.layer;
if (shipComponent.type.animId != null) {
Anim anim = mAnim.get(e);
anim.id = shipComponent.state == ShipComponent.State.UNDER_CONSTRUCTION ? shipComponent.type.buildingAnimId : shipComponent.type.placedAnimId;
anim.id2 = null;
}
}
public int shipValue() {
int count = 0;
for (Entity entity : getActives()) {
if (mc.has(entity)) {
ShipComponent shipComponent = mc.get(entity);
count += shipComponent.type.pointValue;
}
}
return count;
}
/**
* Fetch random ship part.
*/
public Entity getRandomPart() {
final ImmutableBag<Entity> actives = getActives();
return actives.isEmpty() ? null : actives.get(MathUtils.random(0, actives.size() - 1));
}
}