package com.rebelkeithy.ftl.view;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Blending;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.rebelkeithy.ftl.FTLGame;
import com.rebelkeithy.ftl.crew.Crew;
import com.rebelkeithy.ftl.crew.CrewRegistry;
import com.rebelkeithy.ftl.crew.CrewStates;
import com.rebelkeithy.ftl.crew.Race;
import com.rebelkeithy.ftl.crew.Skill;
import com.rebelkeithy.ftl.ship.Direction;
public class CrewRenderer
{
private static Map<String, CrewRenderer>renderers = new HashMap<String, CrewRenderer>();
public static void registerCrewRenderer(Crew crew, CrewRenderer renderer)
{
renderers.put(crew.getName(), renderer);
}
public static CrewRenderer getCrewRenderer(Crew crew)
{
return renderers.get(crew.getName());
}
private Texture texture;
private Texture textureGlow;
private Texture healthBarBg;
private Texture healthLowBarBg;
private Texture healthBar;
private int timer;
private int spriteState;
private int oldDirection;
private double crewOldX;
private double crewOldY;
public CrewRenderer(Crew crew)
{
Race race = CrewRegistry.getRace(crew.getRace());
this.texture = TextureRegistry.getTexture(race.texture);
this.textureGlow = TextureRegistry.getTexture(race.glowTexture);
healthBarBg = TextureRegistry.registerSprite("healthBarBg", "people/health_box");
healthLowBarBg = TextureRegistry.registerSprite("healthLowBarBg", "people/health_box_red");
healthBar = TextureRegistry.getTexture("healthBar");
lowHealth = TextureRegistry.registerSprite("lowHealth", "warnings/health_low");
crewBox = TextureRegistry.getTexture("crewBox");
crewBoxHover = TextureRegistry.getTexture("crewBoxHover");
crewBoxSelected = TextureRegistry.getTexture("crewBoxSelected");
if(crewBox == null)
{
Pixmap crewBoxMap = new Pixmap(86, 27, Format.RGBA8888);
crewBoxMap.setColor(50/256f, 50/256f, 50/256f, 0.5f);
crewBoxMap.fill();
crewBoxMap.setColor(100/256f, 100/256f, 100/256f, 1);
crewBoxMap.drawRectangle(0, 0, 86, 27);
crewBoxMap.drawRectangle(1, 1, 84, 25);
crewBox = new Texture(crewBoxMap);
crewBoxMap.dispose();
TextureRegistry.registerSprite("crewBox", crewBox);
}
if(crewBoxSelected == null)
{
Pixmap crewBoxMap = new Pixmap(86, 27, Format.RGBA8888);
crewBoxMap.setColor(120/256f, 120/256f, 120/256f, 0.5f);
crewBoxMap.fill();
crewBoxMap.setColor(235/256f, 235/256f, 235/256f, 1);
crewBoxMap.drawRectangle(0, 0, 86, 27);
crewBoxMap.drawRectangle(1, 1, 84, 25);
crewBoxSelected = new Texture(crewBoxMap);
crewBoxMap.dispose();
TextureRegistry.registerSprite("crewBoxSelected", crewBoxSelected);
}
if(crewBoxHover == null)
{
int height = 26 + 24*(Skill.getSkills().size()-1);
//height = 26 + 24*5;
Blending old = Pixmap.getBlending();
Pixmap.setBlending(Blending.None);
Pixmap crewBoxMap = new Pixmap(169, height, Format.RGBA8888);
crewBoxMap.setColor(120/256f, 120/256f, 120/256f, 0.5f);
crewBoxMap.fillRectangle(0, 0, 91, 27);
crewBoxMap.fillRectangle(89, 0, 80, height);
crewBoxMap.setColor(235/256f, 235/256f, 235/256f, 1);
crewBoxMap.drawRectangle(0, 0, 91, 27);
crewBoxMap.drawRectangle(1, 1, 89, 25);
crewBoxMap.drawRectangle(89, 0, 80, height);
crewBoxMap.drawRectangle(90, 1, 78, height-2);
for(int i = 0; i < Skill.getSkills().size(); i++)
{
crewBoxMap.drawRectangle(123, 9 + i * 24, 40, 8);
}
crewBoxMap.setColor(120/256f, 120/256f, 120/256f, 0.5f);
crewBoxMap.drawRectangle(89, 2, 2, 23);
Pixmap.setBlending(old);
crewBoxHover = new Texture(crewBoxMap);
crewBoxMap.dispose();
TextureRegistry.registerSprite("crewBoxHover", crewBoxHover);
}
if(healthBar == null)
{
Pixmap healthMap = new Pixmap(3, 3, Format.RGBA8888);
healthMap.setColor(1, 1, 1, 1);
healthMap.fill();
healthBar = new Texture(healthMap);
healthMap.dispose();
TextureRegistry.registerSprite("healthBar", healthBar);
}
skillIcons = new HashMap<String, Texture>();
List<String> skillNames = Skill.getSkills();
for(String skill : skillNames)
{
Texture skillTexture = TextureRegistry.registerSprite(skill.toLowerCase() + "SkillIcon", Skill.getSkill(skill).getIcon());
skillIcons.put(skill, skillTexture);
}
}
public void render(SpriteBatch batch, Crew crew, int shipOffsetX, int shipOffsetY)
{
timer++;
double crewY = crew.getY();
double crewX = crew.getX();
int direction = oldDirection;
if(crewY > crewOldY)
{
direction = Direction.UP;
}
else if(crewY < crewOldY)
{
direction = Direction.DOWN;
}
else if(crewX > crewOldX)
{
direction = Direction.RIGHT;
}
else if(crewX < crewOldX)
{
direction = Direction.LEFT;
}
oldDirection = direction;
crewOldX = crewX;
crewOldY = crewY;
int u = 0;
int v = 0;
float alpha = 1;
Race race = CrewRegistry.getRace(crew.getRace());
if(crew.state == CrewStates.WALKING)
{
if(direction == Direction.UP)
{
if(spriteState >= race.animations.get("walking_up").length)
spriteState = 0;
int frame = race.animations.get("walking_up")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(direction == Direction.LEFT)
{
if(spriteState >= race.animations.get("walking_left").length)
spriteState = 0;
int frame = race.animations.get("walking_left")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(direction == Direction.RIGHT)
{
if(spriteState >= race.animations.get("walking_right").length)
spriteState = 0;
int frame = race.animations.get("walking_right")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(timer%20 == 0)
{
if(crew.isMoving())
{
spriteState++;
}
else
{
spriteState = 0;
}
}
}
if(crew.state == CrewStates.MANNING)
{
u = 35*4;
v = 35*8;
int stationDir = crew.getRoom().getSystem().getStationDir();
if(stationDir == Direction.UP)
{
if(spriteState >= race.animations.get("manning_up").length)
spriteState = 0;
int frame = race.animations.get("manning_up")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(stationDir == Direction.LEFT)
{
if(spriteState >= race.animations.get("manning_left").length)
spriteState = 0;
int frame = race.animations.get("manning_left")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(stationDir == Direction.RIGHT)
{
if(spriteState >= race.animations.get("manning_right").length)
spriteState = 0;
int frame = race.animations.get("manning_right")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(stationDir == Direction.DOWN)
{
if(spriteState >= race.animations.get("manning_down").length)
spriteState = 0;
int frame = race.animations.get("manning_down")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
}
if(timer%10 == 0)
{
Random rand = new Random(System.nanoTime());
int oldstate = spriteState;
while(oldstate == spriteState)
{
spriteState = rand.nextInt(4);
}
}
}
if(crew.state == CrewStates.DYING)
{
u = 3*35;
v = 12*35;
spriteState = (int)(crew.getTimeDead()/200);
if(spriteState >= race.animations.get("death").length)
spriteState = race.animations.get("death").length - 1;
int frame = race.animations.get("death")[spriteState];
v = (frame / (texture.getWidth()/35)) * 35;
u = (frame % (texture.getWidth()/35)) * 35;
if(spriteState == race.animations.get("death").length - 1)
{
alpha = 1 - (crew.getTimeDead() - (200 * race.animations.get("death").length))/(200 * race.animations.get("death").length);
System.out.println(alpha);
if(alpha > 1)
alpha = 1;
if(alpha < 0)
alpha = 0;
spriteState = 4;
}
}
if(crew.state == CrewStates.IDLE)
{
/* DANCING!
if(timer%15 == 0)
{
Random rand = new Random(System.nanoTime());
int oldstate = spriteState;
while(oldstate == spriteState)
{
spriteState = rand.nextInt(4);
}
}
*/
spriteState = 0;
}
//u += spriteState*35;
//TODO: wont work in battle because of extra 150 shift left
int mouseX = Gdx.input.getX() - shipOffsetX;
int mouseY = (Gdx.graphics.getHeight() - Gdx.input.getY()) - shipOffsetY;
boolean hover = false;
if(FTLGame.instance().getPlayer() != null && FTLGame.instance().getPlayer().getName().equals(crew.getHomeShip()))
{
if(mouseX > crew.getX()*35 && mouseX < crew.getX()*35 + 35 && mouseY > crew.getY()*35 && mouseY < crew.getY()*35 + 35)
{
hover = true;
}
}
if(hover == true)
{
FTLView.instance().setTooltipText(crew.getName() + "\nHealth: " + (int)crew.getHealth() + "/" + (int)crew.getMaxHealth(), shipOffsetX + (int)(crew.getX()*35), shipOffsetY + (int)(crew.getY()*35), 35, 35);
}
float health = (float) (crew.getHealth()/crew.getMaxHealth());
boolean lowHealthTimer = (System.currentTimeMillis()/500)%2 == 0 && !hover && health < 0.25;
// Draw health bar
if(FTLView.inputHandler.selected == crew || hover || health < 0.25 && crew.state != CrewStates.DYING)
{
if(lowHealthTimer)
batch.draw(healthLowBarBg, shipOffsetX + (float)crew.getX()*35 - 1, shipOffsetY + (float)crew.getY()*35 + 25);
else
batch.draw(healthBarBg, shipOffsetX + (float)crew.getX()*35 - 1, shipOffsetY + (float)crew.getY()*35 + 25);
batch.setColor(0, 1, 0, 1);
batch.draw(healthBar, shipOffsetX + (float)crew.getX()*35 + 4, shipOffsetY + (float)crew.getY()*35 + 29, health*25, 3);
batch.setColor(1, 1, 1, 1);
}
// Draw crew glow
if(FTLView.inputHandler.selected == crew || hover)
{
TextureRegion regionGlow = new TextureRegion(textureGlow, u, v, 35, 35);
batch.setColor(0, 0.8f, 0, 0.5f);
batch.draw(regionGlow, shipOffsetX + (float)crew.getX()*35, shipOffsetY + (float)crew.getY()*35);
batch.setColor(1, 1, 1, 1);
}
else// if(crew.state != CrewStates.DYING)
{
TextureRegion regionGlow = new TextureRegion(textureGlow, u, v, 35, 35);
batch.setColor(1, 1, 0/156f, 1);
batch.draw(regionGlow, shipOffsetX + (float)crew.getX()*35, shipOffsetY + (float)crew.getY()*35);
batch.setColor(1, 1, 1, 1);
}
TextureRegion region = new TextureRegion(texture, u, v, 35, 35);
batch.setColor(1, 1, 1, alpha);
if(FTLView.inputHandler.selected == crew || hover)
batch.setColor(120/256f, 1, 120/256f, alpha);
batch.draw(region, shipOffsetX + (float)crew.getX()*35, shipOffsetY + (float)crew.getY()*35);
batch.setColor(1, 1, 1, 1);
}
private Texture crewBox;
private Texture crewBoxHover;
private Texture crewBoxSelected;
private Texture lowHealth;
private Map<String, Texture> skillIcons;
boolean hover;
public void renderUI(SpriteBatch batch, Crew crew, int crewNum)
{
int offsetY = -crewNum * 30;
int mouseX = Gdx.input.getX();
int mouseY = Gdx.graphics.getHeight() - Gdx.input.getY();
float health = (float) (crew.getHealth()/crew.getMaxHealth());
if(hover)
hover = mouseX >= 10 + crewBox.getWidth() && mouseX < 10 + crewBoxHover.getWidth() && mouseY > 538+offsetY - (crewBoxHover.getHeight() - crewBox.getHeight()) && mouseY < 538+offsetY+crewBox.getHeight();
if(!hover)
hover = mouseX > 10 && mouseX < 10 + crewBox.getWidth() && mouseY > 538+offsetY && mouseY < 538+offsetY+crewBox.getHeight();
boolean lowHealthTimer = (System.currentTimeMillis()/500)%2 == 0 && !hover && health < 0.25;
if(hover)
{
if(FTLView.inputHandler.selected == crew)
batch.setColor(140/256f, 1, 140/256f, 1);
batch.draw(crewBoxHover, 10, 538 + offsetY - (crewBoxHover.getHeight() - crewBox.getHeight()));
int i = 0;
batch.setColor(1, 1, 1, 1);
for(String skillName : Skill.getSkills())
{
Texture skillTexture = skillIcons.get(skillName);
batch.draw(skillTexture, 103, 538 + offsetY - (i * 24 - 1));
if(mouseX >= 10 + crewBox.getWidth() && mouseX < 10 + crewBoxHover.getWidth() && mouseY > 538 + offsetY - (i * 24 - 1) && mouseY < 538 + offsetY - (i * 24 - 1) + 24)
{
FTLView.instance().setTooltipText(Skill.getSkill(skillName).getTooltip(crew), 10 + crewBox.getWidth(), 538 + offsetY - (i * 24 - 1), crewBoxHover.getWidth() - crewBox.getWidth(), 24);
}
i++;
}
}
else if(FTLView.inputHandler.selected == crew)
{
batch.setColor(140/256f, 1, 140/256f, 1);
batch.draw(crewBoxSelected, 10, 538 + offsetY);
batch.setColor(1, 1, 1, 1);
}
else
{
if(lowHealthTimer)
{
batch.setColor(1, 0.4f, 0.4f, 1);
batch.draw(crewBoxSelected, 10, 538 + offsetY);
batch.setColor(1, 1, 1, 1);
}
else
{
batch.draw(crewBox, 10, 538 + offsetY);
}
}
TextureRegion regionGlow = new TextureRegion(textureGlow, 0, 0, 35, 35);
batch.setColor(1, 1, 0/156f, 1);
batch.draw(regionGlow, 10, 532 + offsetY);
batch.setColor(1, 1, 1, 1);
TextureRegion crewRegion = new TextureRegion(texture, 0, 0 , 35, 35);
batch.draw(crewRegion, 10, 532 + offsetY);
batch.setColor(getHealthColor(health));
batch.draw(healthBar, 43, 542 + offsetY, health*49, 4);
batch.setColor(1, 1, 1, 1);
if(lowHealthTimer)
{
batch.draw(lowHealth, 94, 534 + offsetY);
}
String name = crew.getName();
Fonts.font8.setColor(200/256f, 200/256f, 200/256f, 1);
Fonts.font8.draw(batch, name, 43, 559 + offsetY);
}
public void click(int mouseX, int mouseY, int button, Crew crew, int i)
{
int offsetY = -i * 30;
if(button == 0 && mouseX > 10 && mouseX < 10 + crewBox.getWidth() && mouseY > 538+offsetY && mouseY < 538+offsetY+crewBox.getHeight())
{
FTLView.inputHandler.selected = crew;
}
}
// healthRatio should be a number between 0 and 1
private Color getHealthColor(float healthRatio)
{
if(healthRatio > 0.99)
{
return new Color(0, 1, 0, 1);
}
else if(healthRatio >= 0.5)
{
return new Color(1, 1, 0, 1);
}
else
{
return new Color(1, healthRatio*2, 0, 1);
}
}
}