package com.rebelkeithy.ftl.crew;
import java.util.HashMap;
import java.util.Map;
import com.rebelkeithy.ftl.Clock;
import com.rebelkeithy.ftl.FTLGame;
import com.rebelkeithy.ftl.event.CrewUpdateEvent;
import com.rebelkeithy.ftl.properties.Properties;
import com.rebelkeithy.ftl.ship.Room;
import com.rebelkeithy.ftl.ship.Tile;
import com.rebelkeithy.ftl.systems.AbstractShipSystem;
public class Crew
{
private String race;
private String name;
private String homeShip;
private double health = 100;
private double maxHealth = 100;
private Room room;
private double posX;
private double posY;
private double speed = 0.5;
private double attack = 5;
private double repair = 0.05;
private long deathTimer;
public int state = CrewStates.IDLE;
private CrewPathfinder pathfinder;
private Properties properties;
public Crew(String race, String name)
{
this.name = name;
this.race = race;
maxHealth = 100;
health = 100;
pathfinder = new CrewPathfinder();
properties = new Properties();
}
public void setHomeShip(String ship)
{
homeShip = ship;
}
public boolean addToRoom(Room room)
{
if(room.getSystem() != null && room.getSystem().canMann() && !room.getSystem().isManned())
{
int x = room.getSystem().getStationX();
int y = room.getSystem().getStationY();
System.out.println("adding crew at " + x + " " + y);
setPosition(room, x, y);
state = CrewStates.MANNING;
room.getSystem().mann(this);
return true;
}
for(int tileX = 0; tileX < room.getWidth(); tileX++)
{
for(int tileY = room.getHeight() - 1; tileY >= 0; tileY--)
{
Tile tile = room.getTile(tileX, tileY);
if(!tile.getProperties().containsValue("crew"))
{
setPosition(room, tileX, tileY);
return true;
}
}
}
return false;
}
public void setPosition(Room room, int x, int y)
{
if(this.room != null)
{
this.room.removeCrew(this);
this.room.getTile(x, y).getProperties().removeProperty("crew");
}
this.room = room;
this.posX = room.getX() + x;
this.posY = room.getY() + y;
this.room.getTile(x, y).getProperties().setString("crew", getName());
room.addCrew(this);
}
public void update(double dt)
{
CrewUpdateEvent event = new CrewUpdateEvent(dt, this);
if(homeShip != null)
{
FTLGame.instance().getShip(homeShip).EVENT_BUS.post(event);
}
if(state == CrewStates.WALKING)
{
pathfinder.update(dt, this);
posX = pathfinder.getX();
posY = pathfinder.getY();
if(pathfinder.state == 0)
{
state = CrewStates.IDLE;
}
}
else if(state == CrewStates.REPAIRING)
{
AbstractShipSystem system = room.getSystem();
if(system != null)
{
system.repair(dt, this);
if(system.getDamage() == 0)
{
state = CrewStates.IDLE;
}
}
}
else if(state == CrewStates.MANNING)
{
AbstractShipSystem system = room.getSystem();
if(system.getDamage() > 0)
{
system.unmann();
state = CrewStates.REPAIRING;
}
else if(!system.isPowered())
{
system.unmann();
state = CrewStates.IDLE;
}
}
else if(state == CrewStates.FIGHTING)
{
// TODO: Fight
}
else if(state == CrewStates.IDLE)
{
AbstractShipSystem system = room.getSystem();
//System.out.println(name + " " + system.isPowered());
if(system != null && system.getDamage() > 0)
{
state = CrewStates.REPAIRING;
}
else if(system != null && system.canMann() && !system.isManned() && system.isPowered())
{
int stationX = system.getStationX();
int stationY = system.getStationY();
if(stationX + getRoom().getX() == getX() && stationY + getRoom().getY() == getY())
{
system.mann(this);
state = CrewStates.MANNING;
}
else
{
if(!room.getTile(stationX, stationY).getProperties().containsValue("crew"))
move(getRoom(), stationX, stationY);
}
}
}
}
public void move(Room target)
{
boolean removeFromTile = false;
if(this.state != CrewStates.WALKING)
{
removeFromTile = true;
}
Tile targetTile = pathfinder.setPath(this, target);
if(targetTile != null)
{
if(removeFromTile)
{
System.out.println("removing");
room.getTile((int)getX() - getRoom().getX(), (int)getY() - getRoom().getY()).getProperties().removeProperty("crew");
}
if(state == CrewStates.MANNING)
{
room.getSystem().unmann();
}
state = CrewStates.WALKING;
}
}
public void move(Room target, int x, int y)
{
System.out.println("state " + state);
boolean removeFromTile = false;
if(this.state != CrewStates.WALKING)
{
removeFromTile = true;
}
Tile tile = target.getTile(x, y);
if(tile.getProperties().containsValue("crew"))
return;
Tile targetTile = pathfinder.setPath(this, target, x, y);
if(targetTile != null)
{
if(removeFromTile)
{
System.out.println("removing");
room.getTile((int)getX() - getRoom().getX(), (int)getY() - getRoom().getY()).getProperties().removeProperty("crew");
}
if(state == CrewStates.MANNING)
{
room.getSystem().unmann();
}
state = CrewStates.WALKING;
}
}
public void damage(double amount, String source)
{
// TODO: post damage event
health -= amount;
if(health < 0)
{
health = 0;
kill(source);
}
if(health > maxHealth) // possible if amount is negative, as with healing blast
{
health = maxHealth;
}
}
public void heal(double amount, String source)
{
health += amount;
if(health > maxHealth)
{
health = maxHealth;
}
if(health < 0)
{
kill(source);
}
}
// Will be used to transition into the dying state for animation, then after the animation set dead = true
public void kill(String source)
{
if(state != CrewStates.DYING)
{
Clock.log(name + " died by " + source + "!");
state = CrewStates.DYING;
deathTimer = System.currentTimeMillis();
}
}
public long getTimeDead()
{
return System.currentTimeMillis() - deathTimer;
}
public void remove()
{
if(state == CrewStates.WALKING)
{
pathfinder.cancel(this);
}
else
{
room.getTile((int)getX() - getRoom().getX(), (int)getY() - getRoom().getY()).getProperties().removeProperty("crew");
}
}
public boolean isDead()
{
return state == CrewStates.DYING && getTimeDead() > 2000;
}
public Properties getProperties()
{
return properties;
}
public boolean isMoving()
{
return pathfinder.getState() != pathfinder.IDLE;
}
public String getName()
{
return name;
}
public double getX()
{
return posX;
}
public double getY()
{
return posY;
}
public double getSpeed()
{
return speed;
}
public void setRoom(Room room)
{
this.room = room;
}
public Room getRoom()
{
return room;
}
public double getAttack()
{
return attack;
}
public String getCurrentShip()
{
return room.getShip().getName();
}
public String getHomeShip()
{
return homeShip;
}
public double repairSpeed()
{
return repair;
}
public void setMaxHelth(int maxHealth)
{
this.maxHealth = maxHealth;
}
public void setAttack(double attack)
{
this.attack = attack;
}
public void setRepair(double repair)
{
this.repair = repair;
}
public void setSpeed(double speed)
{
this.speed = speed;
}
public String getRace()
{
return race;
}
public void setHealth(int health)
{
this.health = health;
if(this.health > maxHealth)
this.health = maxHealth;
}
public double getHealth()
{
return health;
}
public double getMaxHealth()
{
return maxHealth;
}
public int getTargetX()
{
return pathfinder.targetX();
}
public int getTargetY()
{
return pathfinder.targetY();
}
}