/*
* This file is part of the Illarion project.
*
* Copyright © 2015 - Illarion e.V.
*
* Illarion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Illarion is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package illarion.client.gui.controller.game;
import de.lessvoid.nifty.elements.Element;
import illarion.client.gui.MiniMapGui.Pointer;
import illarion.client.resources.MiscImageFactory;
import illarion.common.types.ServerCoordinate;
import illarion.common.util.FastMath;
import org.illarion.engine.graphic.Color;
import org.illarion.engine.graphic.Graphics;
import org.illarion.engine.graphic.Sprite;
import org.illarion.engine.nifty.IgeRenderImage;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* This is the implementation of a mini map pointer that marks the starting location of a quest.
*/
final class MiniMapStartPointer implements IgeRenderImage, Pointer {
/**
* The sprite that contains the point, that is displayed on the map.
*/
@Nonnull
private final Sprite pointSprite;
/**
* The location the arrow is supposed to point to.
*/
@Nullable
private ServerCoordinate targetLocation;
/**
* The Nifty-GUI element this pointer is assigned to.
*/
@Nonnull
private final Element parentElement;
/**
* The current delta value of the X coordinates.
*/
private int currentDeltaX;
/**
* The current delta value of the Y coordinates.
*/
private int currentDeltaY;
/**
* This is {@code} true if the quest is available right now.
*/
private boolean available;
/**
* Create a new arrow pointer.
*/
MiniMapStartPointer(@Nonnull Element parentElement) {
pointSprite = MiscImageFactory.getInstance().getTemplate(MiscImageFactory.MINI_MAP_EXCLAMATION).getSprite();
this.parentElement = parentElement;
}
@Override
public int getWidth() {
return pointSprite.getWidth();
}
@Override
public int getHeight() {
return pointSprite.getHeight();
}
@Override
public void dispose() {
// nothing to do
}
@Override
public void renderImage(
@Nonnull Graphics g,
int x,
int y,
int width,
int height,
@Nonnull Color color,
float imageScale) {
renderImage(g, x, y, width, height, 0, 0, pointSprite.getWidth(), pointSprite.getHeight(), color, imageScale,
pointSprite.getWidth() / 2, pointSprite.getHeight() / 2);
}
@Override
public void renderImage(
@Nonnull Graphics g,
int x,
int y,
int w,
int h,
int srcX,
int srcY,
int srcW,
int srcH,
@Nonnull Color color,
float scale,
int centerX,
int centerY) {
int scaledWidth = Math.round(w * scale);
int scaledHeight = Math.round(h * scale);
int fixedX = x + Math.round((w - scaledWidth) * (centerX / (float) w));
int fixedY = y + Math.round((h - scaledHeight) * (centerY / (float) h));
if (isOnMapArea()) {
int offsetX = (FastMath.sqrt(FastMath.sqr(currentDeltaX) / 2) * -FastMath.sign(currentDeltaX)) +
(FastMath.sqrt(FastMath.sqr(currentDeltaY) / 2) * -FastMath.sign(currentDeltaY));
int offsetY = (FastMath.sqrt(FastMath.sqr(currentDeltaX) / 2) * FastMath.sign(currentDeltaX)) +
(FastMath.sqrt(FastMath.sqr(currentDeltaY) / 2) * -FastMath.sign(currentDeltaY));
Color renderColor;
if (available) {
renderColor = POINTER_COLOR;
} else {
renderColor = color;
}
g.drawTexture(pointSprite.getFrame(0), fixedX - offsetX, fixedY - offsetY, scaledWidth, scaledHeight, srcX,
srcY, srcW, srcH, centerX - fixedX, centerY - fixedY, 0.f, renderColor);
}
}
@Override
public void setCurrentQuest(boolean currentQuest) {
}
/**
* This functions returns if this pointer is on the mini map right now or outside of it.
*
* @return {@code true} in case the pointer is on the map
*/
private boolean isOnMapArea() {
return FastMath.sqrt(FastMath.sqr(currentDeltaX) + FastMath.sqr(currentDeltaY)) < 71;
}
void setAvailable(boolean available) {
this.available = available;
}
/**
* Update the angle of arrow.
*
* @param playerLocation the current location of the player
*/
void update(@Nonnull ServerCoordinate playerLocation) {
if (targetLocation == null) {
throw new IllegalStateException("The target location of the pointer is not set. Updating it is illegal.");
}
currentDeltaX = targetLocation.getX() - playerLocation.getX();
currentDeltaY = targetLocation.getY() - playerLocation.getY();
}
@Override
public void setTarget(@Nonnull ServerCoordinate coordinate) {
targetLocation = coordinate;
}
/**
* Get the parent Nifty-GUI element.
*
* @return the parent element
*/
@Nonnull
public Element getParentElement() {
return parentElement;
}
}