package net.alcuria.umbracraft.engine.components;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.definitions.anim.BattleAnimationGroupDefinition;
import net.alcuria.umbracraft.engine.entities.Entity;
import net.alcuria.umbracraft.listeners.Listener;
import net.alcuria.umbracraft.listeners.TypeListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.ObjectMap;
/** A component to handle simple battle animations. Contrary to the
* {@link AnimationGroupComponent}, no logic is done to determine which pose to
* display. Instead, by default it is set to an idle pose and then it is up to
* the programmer to call
* {@link BattleAnimationGroupComponent#setPose(BattlePose)} when a pose change
* is desired.
* @author Andrew Keturi */
public class BattleAnimationGroupComponent implements Component {
public static enum BattlePose {
APPROACH, ATTACK, DEAD, DEFEND, HURT, IDLE, RETURN
}
private ObjectMap<BattlePose, AnimationComponent> animations;
private AnimationComponent currentAnim;
private final BattleAnimationGroupDefinition definition;
private BattlePose delayPose;
private float delaySeconds = 0;
private boolean isMirrored;
/** @param definition the {@link BattleAnimationGroupDefinition} from the
* database. */
public BattleAnimationGroupComponent(BattleAnimationGroupDefinition definition) {
this.definition = definition;
}
@Override
public void create(Entity entity) {
if (definition != null) {
//FIXME: ugly
animations = new ObjectMap<BattlePose, AnimationComponent>();
animations.put(BattlePose.APPROACH, new AnimationComponent(Game.db().anim(definition.towards)));
animations.put(BattlePose.ATTACK, new AnimationComponent(Game.db().anim(definition.attack)));
animations.put(BattlePose.DEAD, new AnimationComponent(Game.db().anim(definition.dead)));
animations.put(BattlePose.HURT, new AnimationComponent(Game.db().anim(definition.hurt)));
animations.put(BattlePose.DEFEND, new AnimationComponent(Game.db().anim(definition.defend)));
animations.put(BattlePose.IDLE, new AnimationComponent(Game.db().anim(definition.idle)));
animations.put(BattlePose.RETURN, new AnimationComponent(Game.db().anim(definition.away)));
for (AnimationComponent anim : animations.values()) {
anim.create(entity);
anim.setMirrorAll(isMirrored);
//anim.setOrigin(origin);
}
currentAnim = animations.get(BattlePose.IDLE);
}
}
@Override
public void dispose(Entity entity) {
}
/** @return the currentComponent */
public AnimationComponent getCurrentAnim() {
return currentAnim;
}
@Override
public void render(Entity entity) {
if (currentAnim != null) {
currentAnim.render(entity);
}
}
/** Sets the listener to invoke when a particular pose animates thru
* @param pose
* @param listener */
public void setAnimationCompleteListener(BattlePose pose, Listener listener) {
animations.get(pose).setCompleteListener(listener);
}
/** Delays for some time before changing the pose. Calls are not queued;
* calling this multiple times before the pose has changed will cancel any
* prior calls scheduled.
* @param delaySeconds the time in seconds to wait before changing the pose
* @param pose the pose to change to after some time has passed */
public void setDelayedPose(float delaySeconds, BattlePose delayPose) {
this.delaySeconds = delaySeconds;
this.delayPose = delayPose;
}
public void setFrameChangedListener(TypeListener<String> listener) {
for (BattlePose key : animations.keys()) {
animations.get(key).setFrameChangedListener(listener);
}
}
/** Sets whether or not to mirror all animations
* @param isMirrored */
public void setMirrorAll(boolean isMirrored) {
this.isMirrored = isMirrored;
if (animations != null) {
for (AnimationComponent anim : animations.values()) {
anim.setMirrorAll(isMirrored);
}
currentAnim.setMirrorAll(isMirrored);
}
}
/** Sets the current pose to render for this component. Be sure
* {@link BattleAnimationGroupComponent#create(Entity)} has been called.
* @param pose the {@link BattlePose}. */
public void setPose(BattlePose pose) {
if (currentAnim != null) {
currentAnim = animations.get(pose);
currentAnim.reset();
}
}
@Override
public void update(Entity entity) {
if (currentAnim != null) {
currentAnim.update(entity);
}
if (delaySeconds > 0) {
delaySeconds -= Gdx.graphics.getDeltaTime();
if (delaySeconds <= 0 && delayPose != null) {
setPose(delayPose);
delayPose = null;
}
}
}
}