/*
* Copyright (c) 2012. HappyDroids LLC, All rights reserved.
*/
package com.happydroids.droidtowers.entities;
import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenCallback;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Vector2;
import com.google.common.eventbus.Subscribe;
import com.happydroids.droidtowers.controllers.AvatarSteeringManager;
import com.happydroids.droidtowers.entities.elevator.Passenger;
import com.happydroids.droidtowers.events.ElevatorHeightChangeEvent;
import com.happydroids.droidtowers.events.GridObjectPlacedEvent;
import com.happydroids.droidtowers.math.GridPoint;
import com.happydroids.droidtowers.tween.TweenSystem;
import static aurelienribon.tweenengine.TweenCallback.COMPLETE;
import static com.happydroids.droidtowers.tween.GameObjectAccessor.POSITION_Y;
public class ElevatorCar extends GameObject {
private final Elevator elevator;
private ElevatorQueue queue;
protected boolean inUse;
private GridPoint finalPosition;
public ElevatorCar(Elevator parent, TextureAtlas elevatorAtlas) {
elevator = parent;
elevator.eventBus().register(this);
finalPosition = new GridPoint();
queue = new ElevatorQueue(elevator);
TextureAtlas.AtlasRegion carRegion = elevatorAtlas.findRegion(elevator.getGridObjectType().getImageFilename());
setRegion(carRegion);
setOrigin(0, 0);
float gridScale = elevator.gameGrid.getGridScale();
setSize(carRegion.originalWidth * gridScale, carRegion.originalHeight * gridScale);
setScale(gridScale);
resetToBottomOfShaft();
}
@Override
protected void finalize() throws Throwable {
if (elevator != null) {
elevator.eventBus().unregister(this);
}
super.finalize();
}
public void moveToFloor(final int nextFloor) {
TweenSystem.manager().killTarget(this);
finalPosition.set(elevator.getPosition());
finalPosition.y = nextFloor;
float targetYPosition = finalPosition.getWorldY();
int distanceBetweenStops = (int) (Math.abs(getY() - targetYPosition) * 2.5f);
Tween.to(this, POSITION_Y, distanceBetweenStops)
.target(targetYPosition)
.delay(500f)
.setCallback(new TweenCallback() {
public void onEvent(int type, BaseTween source) {
queue.arrivedAt(nextFloor);
inUse = false;
}
})
.setCallbackTriggers(COMPLETE)
.start(TweenSystem.manager());
}
@Override
public void update(float timeDelta) {
if (queue.waitingOnRiders()) {
return;
}
for (Passenger currentRider : queue.getCurrentRiders()) {
if (currentRider.isRiding()) {
currentRider.updatePosition(getY());
}
}
if (!inUse) {
if (!queue.moveToNextStop()) {
queue.determinePickups();
}
if (queue.getNextFloor() != ElevatorQueue.INVALID_FLOOR) {
inUse = true;
moveToFloor(queue.getNextFloor());
}
}
}
private void returnToLobby() {
moveToFloor(elevator.getPosition().y);
}
public boolean addPassenger(AvatarSteeringManager steeringManager, int boarding, int destination, Runnable disembarkCallback) {
queue.add(new Passenger(steeringManager, boarding, destination, disembarkCallback));
return true;
}
public void removePassenger(AvatarSteeringManager avatarSteeringManager) {
queue.removePassenger(avatarSteeringManager);
}
public void clearQueue() {
queue.clear();
}
@Subscribe
public void Elevator_boundsChanged(ElevatorHeightChangeEvent event) {
resetToBottomOfShaft();
}
@Subscribe
public void Elevator_boundsChanged(GridObjectPlacedEvent event) {
resetToBottomOfShaft();
}
protected void resetToBottomOfShaft() {
inUse = false;
queue.informPassengersOfServiceChange();
TweenSystem.manager().killTarget(this);
Vector2 elevatorWorldPosition = elevator.getWorldPosition();
setPosition(elevatorWorldPosition.x, elevatorWorldPosition.y + elevator.scaledGridUnit());
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ElevatorCar)) {
return false;
}
ElevatorCar that = (ElevatorCar) o;
return !(queue != null ? !queue.equals(that.queue) : that.queue != null);
}
@Override
public int hashCode() {
return queue != null ? queue.hashCode() : 0;
}
public int getNumRiders() {
return queue.getCurrentRiders().size;
}
public int getNumPassengersWaiting() {
return queue.getPassengersWaiting().size;
}
public boolean isInUse() {
return inUse;
}
}