package com.rebelkeithy.ftl.view;
import java.util.ArrayList;
import java.util.List;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.rebelkeithy.ftl.crew.Crew;
import com.rebelkeithy.ftl.ship.Resource;
import com.rebelkeithy.ftl.ship.Room;
import com.rebelkeithy.ftl.ship.Ship;
import com.rebelkeithy.ftl.systems.AbstractShipSystem;
import com.rebelkeithy.ftl.systems.CommandSystem;
import com.rebelkeithy.ftl.systems.ShieldSystem;
import com.rebelkeithy.ftl.view.events.RenderScrap;
import com.rebelkeithy.ftl.view.scene.SpaceScreen;
public class ShipUIRenderer
{
private Texture hull;
private Texture hullBar;
private Texture fuel;
private Texture missiles;
private Texture drones;
private Texture scrap;
private Texture shieldBar;
private Texture evadeOxygen;
private Texture subsystems;
private Texture powerSlotEmptyLarge;
private Texture powerSlotPoweredLarge;
private Texture ftlBase;
private Texture ftlCharge;
private Texture ftlChargeOff;
private Texture ftlCharging;
private Texture jumpOn;
private Texture jumpOff;
private Texture jumpReady;
private Texture ftlPullout;
private Texture pilotOff;
private Texture pilotOff2;
private Texture pilotOn;
private Texture engineOff;
private Texture engineOff2;
private Texture engineOn;
private Texture ship;
private Texture shipOver;
private Texture shipDisabled;
private Texture wireFull;
private Texture wireMask;
private Texture wire36;
private Texture wire36Cap;
private Texture crewButtonsBase;
private Texture shieldChargeBar;
private List<SystemRenderer> systemRenderers;
private List<SystemRenderer> subsystemRenderers;
private int ftlPulloutTimer;
private Button shipButton;
private Button saveCrewPositionsButton;
private Button sendCrewPositionsButton;
public void init()
{
hull = TextureRegistry.registerSprite("hull", "statusUI/top_hull");
hullBar = TextureRegistry.registerSprite("hull_mask", "statusUI/top_hull_bar_mask");
TextureRegistry.registerSprite("shields_on", "statusUI/top_shields4_on");
TextureRegistry.registerSprite("shields_off", "statusUI/top_shields4_off");
TextureRegistry.registerSprite("shield_dot_on", "statusUI/top_shieldsquare1_on");
TextureRegistry.registerSprite("shield_dot_off", "statusUI/top_shieldsquare1_off");
shieldBar = TextureRegistry.registerSprite("shield_bar", "statusUI/energy_shield_box");
fuel = TextureRegistry.registerSprite("statusUI/top_fuel_on", "statusUI/top_fuel_on");
missiles = TextureRegistry.registerSprite("statusUI/top_missiles_on", "statusUI/top_missiles_on");
drones = TextureRegistry.registerSprite("statusUI/top_drones_on", "statusUI/top_drones_on");
scrap = TextureRegistry.registerSprite("scrap", "statusUI/top_scrap");
evadeOxygen = TextureRegistry.registerSprite("evadeOxygen", "statusUI/top_evade_oxygen");
subsystems = TextureRegistry.registerSprite("subsystems", "box_subsystems4");
ftlBase = TextureRegistry.registerSprite("FTL_base", "buttons/FTL/FTL_base");
ftlCharge = TextureRegistry.registerSprite("FTL_loadingbars", "buttons/FTL/FTL_loadingbars");
ftlChargeOff = TextureRegistry.registerSprite("FTL_loadingbars_off", "buttons/FTL/FTL_loadingbars_off");
ftlCharging = TextureRegistry.registerSprite("FTL_CHARGING", "buttons/FTL/FTL_CHARGING");
jumpOn = TextureRegistry.registerSprite("FTL_JUMP", "buttons/FTL/FTL_JUMP");
jumpOff = TextureRegistry.registerSprite("FTL_JUMP_off", "buttons/FTL/FTL_JUMP_off");
jumpReady = TextureRegistry.registerSprite("FTL_READY", "buttons/FTL/FTL_READY");
ship = TextureRegistry.registerSprite("shipButton", "statusUI/top_ship_on");
shipOver = TextureRegistry.registerSprite("shipButtonOver", "statusUI/top_ship_select2");
ftlPullout = TextureRegistry.registerSprite("FTL_pullout", "buttons/FTL/FTL_pullout");
pilotOff = TextureRegistry.registerSprite("FTL_pilot_off1", "buttons/FTL/FTL_pilot_off1");
pilotOff2 = TextureRegistry.registerSprite("FTL_pilot_off2", "buttons/FTL/FTL_pilot_off2");
pilotOn = TextureRegistry.registerSprite("FTL_pilot_on", "buttons/FTL/FTL_pilot_on");
engineOff = TextureRegistry.registerSprite("FTL_engine_off1", "buttons/FTL/FTL_engine_off1");
engineOff2 = TextureRegistry.registerSprite("FTL_engine_off2", "buttons/FTL/FTL_engine_off2");
engineOn = TextureRegistry.registerSprite("FTL_engine_on", "buttons/FTL/FTL_engine_on");
wireFull = TextureRegistry.registerSprite("wire_full", "wireUI/wire_full");
wireMask = TextureRegistry.registerSprite("wire_mask", "wire_left_mask");
wire36 = TextureRegistry.registerSprite("wire36", "wireUI/wire_36");
wire36Cap = TextureRegistry.registerSprite("wire36Cap", "wireUI/wire_36_cap");
powerSlotEmptyLarge = TextureRegistry.getTexture("powerSlotEmptyLarge");
powerSlotPoweredLarge = TextureRegistry.getTexture("powerSlotPoweredLarge");
Pixmap shieldChargeBarMap = new Pixmap(6, 6, Format.RGBA8888);
shieldChargeBarMap.setColor(27/256f, 132/256f, 1, 1);
shieldChargeBarMap.fill();
shieldChargeBar = TextureRegistry.registerSprite("shieldBar", new Texture(shieldChargeBarMap));
shieldChargeBarMap.dispose();
shipButton = new ShipButton(625, 648, 632, 655, 61, 32, ship);
shipButton.setHoverImage(shipOver);
shipButton.setDownImage(shipOver);
crewButtonsBase = TextureRegistry.registerSprite("button_station_base", "statusUI/button_station_base");
Texture crewButtonSave = TextureRegistry.registerSprite("button_station_assign_on", "statusUI/button_station_assign_on");
Texture crewButtonSaveHover = TextureRegistry.registerSprite("button_station_assign_select2", "statusUI/button_station_assign_select2");
Texture crewButtonSend = TextureRegistry.registerSprite("button_station_return_on", "statusUI/button_station_return_on");
Texture crewButtonSendHover = TextureRegistry.registerSprite("button_station_return_select2", "statusUI/button_station_return_select2");
saveCrewPositionsButton = new Button(10, 500, 10, 500, 20, 20, crewButtonSave);
saveCrewPositionsButton.setHoverImage(crewButtonSaveHover);
saveCrewPositionsButton.setDownImage(crewButtonSaveHover);
sendCrewPositionsButton = new Button(10, 500, 10, 500, 20, 20, crewButtonSend);
sendCrewPositionsButton.setHoverImage(crewButtonSendHover);
sendCrewPositionsButton.setDownImage(crewButtonSendHover);
}
public void initSystemRenderers(Ship ship)
{
systemRenderers = new ArrayList<SystemRenderer>();
// TODO: get list of systems from central location
String[] systemNames = new String[] {"shields", "engines", "health", "oxygen", "weapons"};
int systemX = 77;
for(String name : systemNames)
{
AbstractShipSystem system = ship.getSystem(name);
if(system != null)
{
SystemRenderer renderer = system.getSystemRenderer();
renderer.setX(systemX);
systemRenderers.add(renderer);
systemX += renderer.getWidth();
}
}
}
public void renderFirstLayer(SpriteBatch batch, Ship ship)
{
renderTopButtons(batch, ship);
renderSystems(batch, ship);
renderSubsystems(batch, ship);
renderCrew(batch, ship);
}
public void renderSecondLayer(SpriteBatch batch, Ship ship)
{
renderHull(batch, ship);
renderShields(batch, ship);
renderEvadeOxygen(batch, ship);
renderResources(batch, ship);
renderScrap(batch, ship);
}
private void renderHull(SpriteBatch batch, Ship ship)
{
TextureRegion health = new TextureRegion(hullBar, 0, 0, 12*30, hullBar.getHeight());
batch.setColor(120/256f, 1, 120/256f, 1);
batch.draw(health, 11, 655);
batch.setColor(1, 1, 1, 1);
batch.draw(hull, 0, 655);
}
private void renderScrap(SpriteBatch batch, Ship ship)
{
int numscrap = Resource.getResource("scrap").getResourceAmount(ship);
RenderScrap event = new RenderScrap(batch, numscrap);
FTLView.instance().RENDER_BUS.post(event);
numscrap = event.scrap;
TextBounds bounds = Fonts.numFont.getBounds("" + numscrap);
Fonts.numFont.draw(batch, ""+numscrap, 460 - bounds.width/2, 699);
}
private void renderResources(SpriteBatch batch, Ship ship)
{
// Resource spacing is not uniform
/*List<String> resources = Resource.getResources();
int i = 0;
for(String name : resources)
{
if(name.equals("scrap"))
continue;
Resource resource = Resource.getResource(name);
if(resource.getName().equals("scrap"))
continue;
Texture resourceTexture = TextureRegistry.getTexture(resource.getIcon());
batch.draw(resourceTexture, 117 + 65*i, 637);
i++;
}*/
batch.draw(fuel, 117, 637);
FTLView.instance().setTooltipText(Resource.getResource("fuel").getTooltip(), 127, 637 + 7, fuel.getWidth() - 21, fuel.getHeight() - 14);
batch.draw(missiles, 182, 637);
FTLView.instance().setTooltipText(Resource.getResource("missiles").getTooltip(), 182 + 10, 637 + 7, missiles.getWidth() - 21, missiles.getHeight() - 14);
batch.draw(drones, 252, 637);
FTLView.instance().setTooltipText(Resource.getResource("drones").getTooltip(), 252 + 10, 637 + 7, drones.getWidth() - 21, drones.getHeight() - 14);
batch.draw(scrap, 377, 665);
FTLView.instance().setTooltipText(Resource.getResource("scrap").getTooltip(), 377 + 10, 665 + 7, scrap.getWidth() - 21, scrap.getHeight() - 14);
int numfuel = Resource.getResource("fuel").getResourceAmount(ship);
TextBounds bounds = Fonts.numFont.getBounds(""+numfuel);
Fonts.numFont.draw(batch, ""+numfuel, 168 - bounds.width/2, 664);
int nummissiles = Resource.getResource("missiles").getResourceAmount(ship);
bounds = Fonts.numFont.getBounds(""+nummissiles);
Fonts.numFont.draw(batch, ""+nummissiles, 235 - bounds.width/2, 664);
int numdrones = Resource.getResource("drones").getResourceAmount(ship);
bounds = Fonts.numFont.getBounds(""+numdrones);
Fonts.numFont.draw(batch, ""+numdrones, 302 - bounds.width/2, 664);
}
private void renderShields(SpriteBatch batch, Ship ship)
{
ShieldSystem system = (ShieldSystem) ship.getSystem("shields");
Texture shields = TextureRegistry.getTexture("shields_off");
if(system != null && system.getPower() > 0)
shields = TextureRegistry.getTexture("shields_on");
batch.draw(shields, 0, 612);
batch.draw(shieldBar, 12, 609);
if(system != null)
{
float charge = (float) system.getChargePercent();
batch.draw(shieldChargeBar, 15, 612, charge*92, 6);
}
if(system != null && system.getPower() > 0)
{
for(int i = 0; i < system.maxShields(); i++)
{
Texture shieldDot = TextureRegistry.getTexture("shield_dot_off");
if(system.getShieldLvl() > i)
{
shieldDot = TextureRegistry.getTexture("shield_dot_on");
}
batch.draw(shieldDot, 12 + i*23, 622);
}
}
}
private void renderEvadeOxygen(SpriteBatch batch, Ship ship)
{
batch.draw(evadeOxygen, 0, 565);
int dodge = (int) ((CommandSystem)(ship.getSystem("pilot"))).getDodge();
TextBounds bounds = Fonts.ccFont.getBounds("" + dodge);
Fonts.ccFont.draw(batch, "" + dodge, 82 - bounds.width, 598);
int totalOxygen = 0;
for(Room room : ship.getRooms().values())
{
totalOxygen += (int)(room.getProperties().getDouble("oxygen"));
}
int oxygen = totalOxygen/ship.getRooms().size();
bounds = Fonts.ccFont.getBounds(String.valueOf(oxygen));
Fonts.ccFont.draw(batch, String.valueOf(oxygen), 82 - bounds.width, 584);
}
private void renderCrew(SpriteBatch batch, Ship ship)
{
List<Crew> crew = ship.getCrew();
for(int i = 0; i < crew.size(); i++)
{
CrewRenderer crewRenderer = CrewRenderer.getCrewRenderer(crew.get(i));
crewRenderer.renderUI(batch, crew.get(i), i);
}
batch.draw(crewButtonsBase, 12, 526 - crew.size()*30);
batch.draw(crewButtonsBase, 50, 526 - crew.size()*30);
saveCrewPositionsButton.setPosition(24, 538 - crew.size()*30);
saveCrewPositionsButton.render(batch);
sendCrewPositionsButton.setPosition(62, 538 - crew.size()*30);
sendCrewPositionsButton.render(batch);
}
private void renderTopButtons(SpriteBatch batch, Ship ship)
{
FTLView.instance().setTooltipText("Opens star map to\nchoose jump location\nHotkey: J", 521 + 13, 637, ftlBase.getWidth() - 29, ftlBase.getHeight());
batch.draw(ftlBase, 521, 637);
float shipFtlCharge = (float) ship.getFTLCharge();
// Render FTL Pullout
if(!(ship.getSystem("pilot").isPowered() && ship.getSystem("pilot").isManned() && ship.getSystem("engines").isPowered()))
{
ftlPulloutTimer+=6;
if(ftlPulloutTimer > 48)
ftlPulloutTimer = 48;
}
else
{
ftlPulloutTimer-=6;
if(ftlPulloutTimer < 0)
ftlPulloutTimer = 0;
}
batch.flush();
Rectangle scissors = new Rectangle();
Rectangle clipBounds = new Rectangle(536, 603, 74, 46);
ScissorStack.calculateScissors(((SpaceScreen)FTLView.instance().getScreen()).camera, batch.getTransformMatrix(), clipBounds, scissors);
ScissorStack.pushScissors(scissors);
if(ftlPulloutTimer > 0)
{
batch.draw(ftlPullout, 529, 602 + 48-ftlPulloutTimer);
long time = System.currentTimeMillis();
float alpha = time%2000;
alpha = (-Math.abs(alpha-1000) + 1000)/1000f;
if(ship.getSystem("pilot").isPowered() && ship.getSystem("pilot").isManned())
{
batch.draw(pilotOn, 548, 635 + 48-ftlPulloutTimer);
}
else
{
//batch.setColor(1, 1, 1, alpha);
batch.draw(pilotOff2, 548, 635 + 48-ftlPulloutTimer);
batch.setColor(1, 1, 1, 1-alpha);
batch.draw(pilotOff, 548, 635 + 48-ftlPulloutTimer);
batch.setColor(1, 1, 1, 1);
}
if(ship.getSystem("engines").isPowered())
{
batch.draw(engineOn, 548, 621 + 48-ftlPulloutTimer);
}
else
{
batch.draw(engineOff2, 548, 621 + 48-ftlPulloutTimer);
batch.setColor(1, 1, 1, 1-alpha);
batch.draw(engineOff, 548, 621 + 48-ftlPulloutTimer);
batch.setColor(1, 1, 1, 1);
}
}
batch.flush();
ScissorStack.popScissors();
if(shipFtlCharge < 1)
{
if(ship.getSystem("pilot").isPowered() && ship.getSystem("pilot").isManned() && ship.getSystem("engines").isPowered())
{
TextureRegion chargeRegion = new TextureRegion(ftlCharge, (int) (74*shipFtlCharge), 29);
batch.draw(chargeRegion, 536, 656);
if(ftlPulloutTimer < 10)
{
long time = System.currentTimeMillis();
float color = time%2000;
color = (-Math.abs(color-1000) + 1000)/2000f;
batch.setColor(1, 1, 1 - color, 1);
batch.draw(ftlCharging, 536, 632);
batch.setColor(1, 1, 1, 1);
}
}
else
{
TextureRegion chargeRegion = new TextureRegion(ftlChargeOff, (int) (74*shipFtlCharge), 29);
batch.draw(chargeRegion, 536, 656);
}
}
else
{
if(ship.getSystem("pilot").isPowered() && ship.getSystem("pilot").isManned() && ship.getSystem("engines").isPowered())
{
batch.setColor(1, 1, 0, 1);
batch.draw(jumpOn, 529, 649);
batch.setColor(1, 1, 1, 1);
}
else
{
batch.draw(jumpOff, 529, 649);
}
if(ftlPulloutTimer < 10)
{
long time = System.currentTimeMillis();
float color = time%2000;
color = (-Math.abs(color-1000) + 1000)/2000f;
batch.setColor(1, 1, 1 - color, 1);
batch.draw(jumpReady, 545, 632);
batch.setColor(1, 1, 1, 1);
}
}
shipButton.render(batch);
}
private void initSubsystemRenderers(Ship ship)
{
subsystemRenderers = new ArrayList<SystemRenderer>();
String names[] = {"pilot", "sensors", "doors", "battery"};
int systemX = 1034;
for(String name : names)
{
AbstractShipSystem system = ship.getSystem(name);
if(system != null)
{
SystemRenderer renderer = system.getSystemRenderer();
renderer.setX(systemX);
renderer.setY(42);
subsystemRenderers.add(renderer);
systemX += renderer.getWidth();
}
}
}
private void renderSubsystems(SpriteBatch batch, Ship ship)
{
if(subsystemRenderers == null)
initSubsystemRenderers(ship);
batch.draw(subsystems, 1022, 13);
for(SystemRenderer renderer : subsystemRenderers)
{
renderer.render(batch);
}
}
public void renderSystems(SpriteBatch batch, Ship ship)
{
// Systems
if(systemRenderers == null)
initSystemRenderers(ship);
int systemX = 12;
int systemY = 24;
AbstractShipSystem reactor = ship.getSystem("reactor");
for(int i = 0; i < reactor.getMaxPower(); i++)
{
if(reactor.getPower() > i)
batch.draw(powerSlotPoweredLarge, systemX, 27 + i*9);
else
batch.draw(powerSlotEmptyLarge, systemX, 27 + i*9);
}
// TODO: alpha mask with this
//batch.draw(wireMask, 40, 4 + ship.getSystem("reactor").getMaxPower()*9);
int clip = 33*9 - ship.getSystem("reactor").getMaxPower()*9;
//clip = 40;
batch.draw(new TextureRegion(wireFull, 0, clip, wireFull.getWidth(), wireFull.getHeight()), 33, -17 - clip);
batch.setColor(1, 1, 1, 0.6f);
batch.draw(wireMask, 40, 4 + ship.getSystem("reactor").getPower()*9);
batch.setColor(1, 1, 1, 1);
systemX += 65;
for(SystemRenderer renderer : systemRenderers)
{
renderer.render(batch);
if(renderer == systemRenderers.get(systemRenderers.size()-1))
{
batch.draw(wire36Cap, systemX-24, systemY-22);
}
else if(renderer != systemRenderers.get(0))
{
batch.draw(wire36, systemX-24, systemY-22);
}
systemX += renderer.getWidth();
}
}
public boolean click(int screenX, int screenY, int button)
{
for(SystemRenderer renderer : subsystemRenderers)
{
if(renderer.click(screenX, screenY, button))
{
return true;
}
}
for(SystemRenderer renderer : systemRenderers)
{
if(renderer.click(screenX, screenY, button))
{
return true;
}
}
if(shipButton.containsPoint(screenX, screenY))
{
if(button == 0)
shipButton.leftClick();
return true;
}
return false;
}
}